给定以下代码:
class Base {
public:
virtual void Test() {
cout << "Not Overridden" << endl;
}
};
class Derived : public Base {
public:
void Test() override {
cout << "Overridden" << endl;
}
};
int main() {
Base o = Derived();
o.Test();
return 0;
}
像我这样有Java背景的人希望编译器输出overridded
,但令人惊讶的是,输出结果恰恰相反。 如果这是一种正常的行为,那么在C++中继承又有什么意义呢? 不然,我错过了什么?
是的,这是正常的行为,多态性只适用于指针和引用。
int main() {
Base* o = new Derived();
o->Test();
return 0;
}
或
int main() {
Derived d;
Base& o = d;
o.Test();
return 0;
}
输出:
Overridden
网站上的一些线程解释了为什么会这样,就像这个。
您拥有它的方式导致对象切片。
您还需要向基类添加一个虚拟析构函数。
Base o = Derived();
上面的o
是一个对象--一个基
对象--而不是一个派生
对象。 O
对象是通过对象切片从派生
对象创建的,但O
仍然是基
对象。 这里没有动态分派,因此o.test()
导致调用base::test()
。
相反,如果将O
声明为引用您创建的派生
对象的基
指针:
int main() {
Base* o = Derived(); // o is a pointer
o->Test();
return 0;
}
在这种情况下,O
是指向对象的指针--与对象相反--并且动态分派生效:即使O
是指向基
对象的指针,它也绑定到派生
对象,因此O->test()
导致由于动态分派而导致这次调用派生::test()
。
类似地,如果o
是对base
的引用,而不是指针。