多态算子<<来自虚拟基类

时间:2015-06-02 23:54:47

标签: c++ inheritance polymorphism operator-overloading

我想重载Operator<<在多态类的上下文中进行专门的操作。给出我想要的直接示例(使用int作为示例):

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

我想使用这种语法,因为我的程序的另一部分使用&lt;&lt;,但在非多态类上执行相同的操作。

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

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是抽象的。

我不能将重载只放在继承的类中,因为我需要从指向基类的指针访问运算符而不转换为子类。

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

3 个答案:

答案 0 :(得分:3)

您的代码无法正常工作,因为它是纯虚拟的,因此无法返回Base个对象。请改为引用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)的重载不会返回Base&,而是返回A&B&。这称为协方差

答案 1 :(得分:1)

您可以将ConnectionError: HTTPConnectionPool(host='apicache.vudu.com', port=80): Max retries exceeded with url:的作业委派给纯虚函数,您可以在所有派生类中覆盖它,例如

Base::operator<<

Live on Coliru

答案 2 :(得分:0)

如果要使用多态,则不应按值返回。你应该通过引用返回。

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

#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;
}