多态运算符<< 来自虚基 class

Polymorphic operator<< from virtual base class

我想重载 Operator<< 以在多态 classes 的上下文中执行专门的操作。举个我想要的直接例子(以int为例):

Base* a = new A;
(*a) << 10;

我想使用这种语法,因为我的程序的另一部分使用 << 执行相同的操作,但在非多态 classes.

问题是,Base 是纯虚拟的,我不知道如何在没有完整有效的 Base 的情况下实现这种系统 class。例如:

class Base
{
public:
    virtual void aVirtualFunction() = 0;
    virtual Base operator<<( int ) = 0;
};

class A : public Base
{
    Base operator<<( int )
    {
        // Do something
    }
};

class B : public Base
{
    Base operator<<( int )
    {
        // Do something
    }
};

这会产生错误,因为 Base 是抽象的。

我不能只在继承的 classes 中放置重载,因为我需要从指向基 class 的指针访问运算符而不强制转换为子对象。

我的问题与 Overloading << operator with polymorphism 中提出的问题非常相似,只是我的基础 class 本身不是有效对象。

如果你想使用多态性,你不应该 return 按值。您应该 return 作为参考。

请注意,您的 operator<< 未在您的基础 class 中声明为虚拟。

#include <iostream>

class Base
{
public:
    virtual void aVirtualFunction() = 0;
    virtual Base& operator<<( int ) = 0;
};

class A : public Base
{
    public:
    A& operator<<( int a)
    {
        // Do something
        a_ = a;
        return *this;
    }

    void aVirtualFunction()
    {
        std::cout << a_ << '\n';
    }

    int a_;
};

class B : public Base
{
    public:
    B& operator<<( int a)
    {
        // Do something
        b_ = a;
        return *this;
    }

    void aVirtualFunction()
    {
        std::cout << b_ << '\n';
    }

    int b_;
};

int main(int, char**)
{
    Base* a = new A;
    Base* b = new B;
    *a << 10;
    *b << 11;

    a->aVirtualFunction();
    b->aVirtualFunction();

    delete a;
    delete b;
}

您的代码无法工作,因为您不能 return 一个 Base 对象,因为它是纯虚拟的。 Return 改为引用 Base

然后,使用标准继承就可以轻松处理整个事情。考虑以下代码:

class Base
{
public:
    virtual void aVirtualFunction() = 0;
    virtual Base& operator<<( int ) = 0;
};

class A : public Base
{
    virtual A& operator<<( int ) override
    {
        // Do something
        return *this;
    }
};

class B : public Base
{
    virtual B& operator<<( int ) override
    {
        // Do something
        return *this;
    }
};

DEMO

请注意 operator<<(int) 的重载不是 return Base&,而是 A&B&。这称为 协方差.

您可以将 Base::operator<< 的工作委托给一个纯虚函数,您可以在所有派生的 类 中覆盖它,例如

#include <iostream>
#include <memory>

class Base
{
    virtual void delegate(int x) = 0;
public:
    Base& operator<<( int x) // we define this only in Base
    {
        delegate(x); // delegate, this must be overridden in all derived classes
        return *this;
    }
    virtual ~Base() = default;
};

void Base::delegate(int x) // we can even define this
{
    std::cout << "Base::delegate x = " << x << std::endl;
}

class A : public Base
{
    void delegate(int x) override
    {
        std::cout << "A::delegate x = " << x << std::endl;
    }
};

class B : public Base
{
    void delegate(int x) override
    {
        std::cout << "B::delegate x = " << x << std::endl;
    }
};

int main()
{
    std::unique_ptr<Base> pBase(new B);
    *pBase << 42;
}

Live on Coliru