使运算符<<虚拟?

时间:2010-12-31 18:12:04

标签: c++ operators operator-overloading virtual

我需要使用虚拟<<运营商。但是,当我试着写:

virtual friend ostream & operator<<(ostream& os,const Advertising& add);

我收到编译错误

  

错误1错误C2575:'operator&lt;&lt;' :   只有成员职能和基地才可以   虚拟

如何将此运算符设为虚拟?

3 个答案:

答案 0 :(得分:73)

此设置的问题在于运营商&lt;&lt;你在上面定义的是一个自由函数,它不能是虚拟的(它没有接收者对象)。为了使函数成为虚函数,必须将它定义为某个类的成员,这在这里是有问题的,因为如果你定义operator&lt;&lt;作为一个类的成员,那么操作数将是错误的顺序:

class MyClass {
public:
    virtual ostream& operator<< (ostream& out) const;
};

表示

MyClass myObject;
cout << myObject;

不会编译,但

MyClass myObject;
myObject << cout;

将是合法的。

要解决此问题,您可以应用软件工程的基本定理 - 任何问题都可以通过添加另一层间接来解决。而不是使运营商&lt;&lt;虚拟,考虑在类中添加一个新的虚函数:

class MyClass {
public:
    virtual void print(ostream& where) const;
};

然后,定义运算符&lt;&lt;如

ostream& operator<< (ostream& out, const MyClass& mc) {
    mc.print(out);
    return out;
}

这样,运营商&lt;&lt;自由函数具有正确的参数顺序,但运算符的行为&lt;&lt;可以在子类中自定义。

希望这有帮助!

答案 1 :(得分:31)

您定义了运算符&lt;&lt;调用虚拟打印方法:

class Base
{
    protected:
        virtual void print(std::ostream& str) const = 0;
    public:
        friend std::ostream& operator<<(std::ostream& str, Base const& data)
        {
            data.print(str);
            return str;
        }
}

答案 2 :(得分:2)

看起来您真的想为类层次结构提供输出功能,如果是这样,您可以提供调用friend operator <<函数的virtual

class Parent
{
public:
    friend std::ostream& operator<< (std::ostream& os, const Parent& p);
    // ... other class stuff
protected:
    virtual void printMyself(std::ostream& os) const
    {
        // do something if you must, or make this a pure virtual
    }
};

std::ostream& operator<< (std::ostream& os, const Parent& p)
{
    p.printMyself(os);
    return os;
}

class Child : public Parent
{
    // other class stuff...
protected:
    virtual void printMyself(std::ostream os) const
    {
        // whatever you need to do
    }
};

C++ FAQ

中还有详细说明