use*_*431 1 c++ inheritance covariance
我得到了一个意想不到的结果,到目前为止我无法解释自己.
虽然生成了同一类BASIC2(继承自BASIC1)的对象两次,但operator<<在生成的对象上使用朋友时会生成不同的消息.
见下面的代码
我让D(Derived继承Base的类的对象)生成类的对象BASIC2并将其称为朋友operator<<.这会产生预期的消息"BASIC2 object".
我让B生成一个类的对象BASIC1并调用它的朋友operator<<.这"BASIC1 object"按照我的预期输出.
然后我使用虚拟继承让let B2(Base* B2 = &D;)生成一个对象BASIC2.我遵循调试器中的代码流(Visual Studio 2010),这正确地生成了一个对象BASIC2.但是,朋友operator<<没有被调用BASIC2对象,而是使用operator<<来自类的朋友BASIC1(因此输出"BASIC1 object").
另请注意,我确实希望BASIC2继承,BASIC1因为我想利用协方差行为.
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");
}
Run Code Online (Sandbox Code Playgroud)
输出是:
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:
};
Run Code Online (Sandbox Code Playgroud)
operator <<的选择基于编译期间已知对象的静态类型.要实现你想要的,不要定义两个operator <<函数,但只能在BASIC1中定义一个:
friend std::ostream& operator<<(std::ostream& os, const BASIC1& basic) {
Write(os);
return os;
}
Run Code Online (Sandbox Code Playgroud)
并定义虚函数在BASIC1和BASIC2中写入以执行您想要的操作:
virtual void Write(std::ostream& os) const {
os << "BASIC1 object";
}
Run Code Online (Sandbox Code Playgroud)