我得到了意外的结果,到目前为止我还无法解释自己。

尽管两次生成了相同类BASIC2的对象(继承自BASIC1),但在生成的对象上使用 friend operator<<时却生成了不同的消息。

见下面的代码

我让D(继承自DerivedBase类的对象)生成BASIC2类的对象,并将其称为 friend operator<<。这将产生预期的消息"BASIC2 object"

我让B生成类BASIC1的对象,并将其称为operator<<。如我期望的那样输出"BASIC1 object"

然后,我使用虚拟继承让B2(Base* B2 = &D;)生成BASIC2的对象。我遵循调试器(Visual Studio 2010)中的代码流,这将正确生成BASIC2对象。但是, friend operator<<不会在BASIC2对象上调用,而是使用类operator<<中的 friend BASIC1(因此输出"BASIC1 object")。

还要注意,我确实希望BASIC2BASIC1继承,因为我想利用协方差行为。

int main(int argc, char* argv[]) {
    Base B;
    Derived D;
    Base* B2 = &D;
    std::cout << *D.generate(0) << std::endl;
    std::cout << *B.generate(0) << std::endl;
    std::cout << *(B2->generate(0)) << std::endl;
    system("pause");
}

输出为:
BASIC2 object
BASIC1 object
BASIC1 object
class BASIC1 {
public:
    friend std::ostream& operator<<(std::ostream& os, const BASIC1& basic) {
    os << "BASIC1 object";
    return os;
    }
};

class BASIC2 : public BASIC1 {
    friend std::ostream& operator<<(std::ostream& os, const BASIC2& basic) {
    os << "BASIC2 object";
    return os;
    }
};

class Base {
public:
    virtual BASIC1* generate(double num) const {
    return new BASIC1();
    }
protected:
private:
};

class Derived : public Base {
public:
    virtual BASIC2* generate(double num) const override {
    return new BASIC2();
    }
protected:
private:
};

最佳答案

选择operator <

    friend std::ostream& operator<<(std::ostream& os, const BASIC1& basic) {
      Write(os);
      return os;
    }

并定义虚拟函数同时在BASIC1和BASIC2中写入以执行所需的操作:
virtual void Write(std::ostream& os) const {
   os << "BASIC1 object";
}

09-05 21:41