代码之家  ›  专栏  ›  技术社区  ›  Omri. B

二进制表达式的操作数无效('std::ostream'(又名'basic\u ostream<char>')和'sound\u ctl')

  •  0
  • Omri. B  · 技术社区  · 4 年前

    我想写一本书 << 接线员。我的代码:

    #include <iostream>
    #include <ostream>
    class sound_ctl {
    private:
        int _vol;
        bool _status;
    public:
        sound_ctl() : _vol(50), _status(false) {};
    
        void operator++() {
            if (_vol <= 98) {
                _vol += 2;
            }
        }
    
        void operator--() {
            if (_vol >= 2) {
                _vol -= 2;
            }
        }
    
        void operator!() {
            _status = !_status;
        }
    
        std::ostream &operator<<(std::ostream &os) const {
            os << _status << "Volume: " + _vol << std::endl;
            return os;
        }
    
    };
    
    
    int main() {
        sound_ctl panel1;
        std::cout << panel1;
    }
    

    但是,代码编译时不会出错: Invalid operands to binary expression ('std::ostream' (aka 'basic_ostream<char>') and 'sound_ctl')

    我对c++中的流非常缺乏理解,因此,理解底层问题将对我有很大帮助。谢谢

    2 回复  |  直到 4 年前
        1
  •  2
  •   rawrex    4 年前

    不应将输入/输出运算符定义为成员函数。

    std::ostream &operator<<(std::ostream &os, const sound_ctl& sc) {
        os << sc._status << "Volume: " + sc._vol << std::endl;
        return os;
    }
    

    然后将此函数声明为友元:

    class sound_ctl {
    friend std::ostream &operator<<(std::ostream &os, const sound_ctl& sc);
    // ...
    };
    

    为什么不能像这样调用output std::cout << panel1 ,对你来说?因为 << operator<<() 功能。如果此函数是成员函数,则左侧将作为隐式传递 this ,而右侧将是参数列表中的参数。意味着您必须这样调用输出:

    panel1 << std::cout; // No comments...
    

    我们通过将类的对象作为显式的第二个参数传递给运算符来避免: ostream& operator<<(ostream&, const sound_ctl&)

    thread . 这也会有帮助: Overloading The IO Operators .

    另外,请注意 模拟内置操作符 在重载运算符中。所以,你的 operator++ 还要定义后缀 递增/递减运算符。

        2
  •  1
  •   Remy Lebeau    4 年前

    所有运算符的实现都不正确。看到了吗 What are the basic rules and idioms for operator overloading? .

    但是,关于 operator<< 具体来说,它不能作为类的成员实现,它必须是独立函数。它需要2个参数,流被写入,对象被写入。

    试试这个。

    #include <iostream>
    #include <ostream>
    
    class sound_ctl {
    private:
        int _vol;
        bool _status;
    public:
        sound_ctl() : _vol(50), _status(false) {};
    
        sound_ctl& operator++() {
            if (_vol <= 98) {
                _vol += 2;
            }
            return *this;
        }
    
        sound_ctl operator++(int) {
            sound_ctl tmp(*this);
            ++(*this);
            return tmp;
        }
    
        sount_ctl& operator--() {
            if (_vol >= 2) {
                _vol -= 2;
            }
            return *this;
        }
    
    
        sound_ctl operator--(int) {
            sound_ctl tmp(*this);
            --(*this);
            return tmp;
        }
    
        bool operator!() const {
            return !_status;
        }
    
        // even though this is inlined within the class declaration,
        // it is NOT actually a member of the class!
        friend std::ostream& operator<<(std::ostream &os, const sound_ctl& ctl) {
            os << ctl._status << " Volume: " + ctl._vol << std::endl;
            return os;
        }
    };
    
    int main() {
        sound_ctl panel1;
        std::cout << panel1;
    }
    

    #include <iostream>
    #include <ostream>
    
    class sound_ctl {
    private:
        int _vol;
        bool _status;
    public:
        sound_ctl() : _vol(50), _status(false) {};
    
        sound_ctl& operator++() {
            if (_vol <= 98) {
                _vol += 2;
            }
            return *this;
        }
    
        sound_ctl operator++(int) {
            sound_ctl tmp(*this);
            ++(*this);
            return tmp;
        }
    
        sount_ctl& operator--() {
            if (_vol >= 2) {
                _vol -= 2;
            }
            return *this;
        }
    
    
        sound_ctl operator--(int) {
            sound_ctl tmp(*this);
            --(*this);
            return tmp;
        }
    
        bool operator!() const {
            return !_status;
        }
    
        void print(std::ostream &os) const {
            os << _status << " Volume: " + _vol << std::endl;
        }
    };
    
    std::ostream& operator<<(std::ostream &os, const sound_ctl& ctl) {
        ctl.print(os);
        return os;
    }
    
    int main() {
        sound_ctl panel1;
        std::cout << panel1;
    }