在虚拟方法上使用引用时,我遇到了一些意外行为。 基本上,如果我引用基类的对象,则将该引用更改为派生类的对象。当我调用虚方法时,会调用基类方法。
但是如果我引用基类并将其初始化为派生类,则调用派生方法。这是一些代码。
// A base class with a virtual that prints the class
class BaseClass {
public:
virtual void printMe();
};
class DerivedClass : public BaseClass {
public:
void printMe() override;
};
void BaseClass::printMe() {
cout << "in Base"<<endl;
}
void DerivedClass::printMe() {
cout << "in Derived"<<endl;
}
int main () {
BaseClass bc = BaseClass();
DerivedClass dc = DerivedClass();
BaseClass * pbc = & bc ;
pbc->printMe(); // Prints in Base
pbc = & dc;
pbc->printMe(); // Prints in Derived
// Now with a reference
BaseClass & bcr = bc;
bcr.printMe(); // Prints in Base
bcr = dc;
bcr.printMe(); // Prints in Base !!!
BaseClass & foo = dc;
foo.printMe(); // Prints in Derived !!!
return 0;
}
如果有人能解释为什么第四张印刷品不是&#34;在Derived&#34;为什么第五个是&#34;在Derived&#34;我将不胜感激。
我(现在)了解有关切片的内容 - 但根据这个逻辑,我不明白为什么
BaseClass & foo = dc;
foo.printMe()
调用派生方法
没关系我现在看到了。
答案 0 :(得分:1)
必须初始化引用,但永远不会分配。
这意味着当您执行:bcr = dc;
时,您不使bcr
引用dc
。相反,您将获取dc
的值,“切片”它以创建基类的临时对象,然后将该临时对象分配给bcr
引用的对象(即{{ 1}})。之后,bc
仍然引用dcr
,bc
已分配了一个新值(来自bc
的基类子对象)。
一旦引用引用一个对象(必须发生 as 引用是create),它就可以/将始终引用该对象。任何分配尝试都会分配给它引用的那个对象,不到引用本身。
答案 1 :(得分:1)
此:
dc
不会将bcr = dc;
分配给dc
。
它将执行切片。它将切断派生类与基类相比所有额外的东西(换句话说,它会将派生类视为基类)。