Sha*_*fiz 5 c++ polymorphism virtual-functions object-reference
请考虑以下代码段:
class Window // Base class for C++ virtual function example
{
public:
virtual void Create() // virtual function for C++ virtual function example
{
cout <<"Base class Window"<<endl;
}
};
class CommandButton : public Window
{
public:
void Create()
{
cout<<"Derived class Command Button - Overridden C++ virtual function"<<endl;
}
};
int main()
{
Window *button = new CommandButton;
Window& aRef = *button;
aRef.Create(); // Output: Derived class Command Button - Overridden C++ virtual function
Window bRef=*button;
bRef.Create(); // Output: Base class Window
return 0;
}
Run Code Online (Sandbox Code Playgroud)
无论阿里夫和BREF得到分配的*键,偏偏是两个不同的输出.分配参考类型和非参考类型有什么区别?
Mar*_*ork 10
您遇到了切片问题.
Window bRef =*button;
Run Code Online (Sandbox Code Playgroud)
这里bRef不是引用而是对象.当您将派生类型分配到bRef时,您正在切换派生部分,只留下一个由CommandButton构造的Window对象.
发生的事情是使用编译器生成的类Window的复制构造函数在上面的语句中创建bRef.所有这些构造函数都是将成员元素从RHS复制到新构造的对象.由于班级中没有成员,因此没有任何事情发生.
旁注:具有虚拟成员的类也应该具有虚拟析构函数.
aRef有Window 静态类型但CommandButton 动态类型bRef只是类型的对象Window(所述CommandButton "部分"在拷贝丢失)这通常称为对象切片,它通常通过使基类抽象(通过提供纯虚函数)或不可复制(例如使用boost::noncopyable)来防止,因为任何一种解决方案都会使代码无法在线编译Window& aRef = *button;.
现在,为什么bRef.Create()打电话Window::Create?嗯,只有一个Window,bRef所以没有太多的选择.这基本上就像声明Window并调用Create它一样:bRef从CommandButton实例复制的事实是无关紧要的,因为该CommandButton部分在副本中丢失了.
我将通过引用标准(10.3/6)来尝试使其更清晰:
[注意:虚函数调用的解释取决于调用它的对象的类型(动态类型),而非虚拟成员函数调用的解释仅取决于指针的类型或表示该对象的引用(静态类型)(5.2.2).]
只有通过指针或引用间接,对象的静态类型才能与其动态类型不同.