重载<<派生类的运算符表示无效的操作数

时间:2019-02-27 15:05:08

标签: c++ inheritance operator-overloading virtual

class A {
    //does stuff

public:
    virtual std::ostream& operator<< (std::ostream& os) = 0;
};

class B : public A {
public:
    //does similiar stuff

    virtual std::ostream& operator<< (std::ostream& os) {
        os << "x" << std::endl;
    }
}

class C {
public:
    A* array[10];

    A* & operator()(int a) {
        // in my code, it is a 2D array indexed with (),
        // but that's irrelevant here
        return array[a];
    }
}

int main(){
    C c = C();

    //in for loop we say c(i) = new B();
    for(int i=0; i<10; i++){
        std::cout << *(c(i)); // error
    }

    return 0;
}

我猜测问题是我的()运算符返回的是基本指针,而不是B指针,而A没有<<。但是,使用模板进行索引也不能解决问题,只会使其变得怪异。

有什么想法吗?

1 个答案:

答案 0 :(得分:2)

问题是您将operator<<作为 member 函数重载。这意味着它只能用作例如

instance_of_B << std::cout;

翻译成

instance_of_B.operator<<(std::cout);

如果要重载<<作为流输出运算符,则它必须是 non 成员函数,并将流作为第一个参数,并将A (或派生)对象作为第二个参数。

要处理输出,可以使用一个虚拟成员函数来执行输出,并由非成员operator<<函数调用。

也许类似

class A
{
public:
    ...

    // Inline definitions of friend functions makes the functions non-member functions
    friend std::ostream& operator<<(std::ostream& os, A const& a)
    {
        return a.output(os);
    }

protected:
    virtual std::ostream& output(std::ostream&) = 0;
};

class B
{
    ...

protected:
    std::ostream& output(std::ostream& os) override
    {
        return os << "Output from the B class\n";
    }
};