销毁对象是否会停止后期绑定? 考虑以下C++类继承层次结构及其预期的多态行为。 #include <iostream> using namespace std; class A { public: A () { cout << "A constructor\n"; } virtual void display() { cout << "A display\n"; } virtual ~A() { cout << "A destructor\n"; } friend ostream& operator << (ostream &out, A &a) { a.display(); return out; } }; class B : public A { public: B () { cout << "B constructor\n"; } virtual void display() { cout << "B display\n"; } virtual ~B() { cout << "B destructor\n"; } }; class C : public B { public: C () { cout << "C constructor\n"; } virtual void display() {cout << "C display\n";} virtual ~C() { cout << "C destructor\n"; } }; int main() { C c1; cout << endl; c1.display(); cout << endl; c1.~C(); cout << endl; c1.display(); cout << endl; c1.~C(); cout << "=================================================" << endl; C c2; cout << endl << c2 << endl; c2.~C(); cout << endl << c2 << endl; c2.~C(); return 0; } #包括 使用名称空间std; 甲级 { 公众: A(){cout

销毁对象是否会停止后期绑定? 考虑以下C++类继承层次结构及其预期的多态行为。 #include <iostream> using namespace std; class A { public: A () { cout << "A constructor\n"; } virtual void display() { cout << "A display\n"; } virtual ~A() { cout << "A destructor\n"; } friend ostream& operator << (ostream &out, A &a) { a.display(); return out; } }; class B : public A { public: B () { cout << "B constructor\n"; } virtual void display() { cout << "B display\n"; } virtual ~B() { cout << "B destructor\n"; } }; class C : public B { public: C () { cout << "C constructor\n"; } virtual void display() {cout << "C display\n";} virtual ~C() { cout << "C destructor\n"; } }; int main() { C c1; cout << endl; c1.display(); cout << endl; c1.~C(); cout << endl; c1.display(); cout << endl; c1.~C(); cout << "=================================================" << endl; C c2; cout << endl << c2 << endl; c2.~C(); cout << endl << c2 << endl; c2.~C(); return 0; } #包括 使用名称空间std; 甲级 { 公众: A(){cout,c++,inheritance,polymorphism,virtual-functions,late-binding,C++,Inheritance,Polymorphism,Virtual Functions,Late Binding,销毁一个对象会使继续调用该对象的成员函数成为非法行为。您的代码行为未定义,您观察到的任何行为都不能依赖于在同一程序的运行中保持,更不用说不同的编译器标志或完全不同的实现了 但是,我们可以猜测为什么您会看到您报告的特定行为,因为我们不应该在将来继续编译和运行此类代码,因为它的行为无法得到保证 您的编译器可能正在对c1.display()调用进行设备化,因为它可以看到c1的定义(因此知道它的动态类型是C)。因此,生成的代码可能根本不参考vtable。这解释了为什么您继续看到“C display”即使

销毁一个对象会使继续调用该对象的成员函数成为非法行为。您的代码行为未定义,您观察到的任何行为都不能依赖于在同一程序的运行中保持,更不用说不同的编译器标志或完全不同的实现了

但是,我们可以猜测为什么您会看到您报告的特定行为,因为我们不应该在将来继续编译和运行此类代码,因为它的行为无法得到保证

您的编译器可能正在对
c1.display()
调用进行设备化,因为它可以看到
c1
的定义(因此知道它的动态类型是
C
)。因此,生成的代码可能根本不参考vtable。这解释了为什么您继续看到“C display”即使物体已经被摧毁


c2
情况下,对象是通过引用传递的,编译器可能没有足够积极地内联,无法对最终的
display
调用进行反虚拟化。如果它在
c2
销毁后查阅vtable,它可能会找到
A
的vtable,因为
C的销毁过程A::~A
之前,code>对象必须最终重置
A
子对象的vptr,以指向
A
vtable(如果
A::~A
调用任何虚拟函数)。这就解释了“A显示”消息。

对OP的代码是如何错误的进行了出色的分析。仅供参考:§C++17的§6.8 1.3和6.8 7.2与观察到的行为相关。§15.4 16也与代码相关,但不会导致问题中提到的行为。§15.7 3与问题中的代码无关因为它涵盖了构造函数和析构函数中调用的虚函数的解析。