下面是C ++中虚拟函数最简单的例子:
#include <iostream>
class A {
public:
virtual void f() {
std::cout << "A";
}
};
class B : public A {
public:
void f() {
std::cout << "B";
}
};
int main() {
{
// calls f() in derived class
A* a = new B();
a->f();
}
{
// calls f() in base class
A a = B();
a.f();
}
}
此程序的输出为BA
。我希望它是BB
,即在任何情况下调用基类。
为什么使用基类指针会有所不同?
我没有在标准中找到解释。
答案 0 :(得分:7)
这称为slicing。 A a = B();
创建一个A
类型的副本。有关其来源B
的所有信息都被遗忘了。利用多态的唯一方法是通过引用或指针(或允许编译时多态的机制,例如模板或函数重载)。
答案 1 :(得分:3)
多态性与指针一起使用,因为在指针(或引用)的情况下,您可以区分指针的类型和对象的类型。现在在以下代码中:
A a = B();
a.f();
发生的事情称为切片。即对象B()被切片,其基础A()被分配给。
不要忘记让析构函数虚拟化!
答案 2 :(得分:0)
在A a = B()
的情况下,函数调用的顺序是:
总结一下,这是上面一行的“完整版”:A(B()->operator A())