64,676
社区成员
发帖
与我相关
我的任务
分享
#include <iostream>
class B
{
public:
virtual ~B() { std::cout << "B" << std::endl; }
};
class D : public B
{
public:
virtual ~D() { std::cout << "D" << std::endl; }
};
int main(int, char * [])
{
D d;
B & b = d;
b.~B();
std::cout << "---" << std::endl;
b.~B(); // why?
std::cout << "---" << std::endl;
return(0);
}
D
B
---
B // 这里怎么就没多态了?
---
D
B
class A
{
public:
void f()
{}
};
int main()
{
A * a;
a.f();
}
这样的代码在C++中也是允许的,在集合C++的虚函数表你就明白你的问题了。如此大华不缺牛人,我只是一个一年半工作经验的本科生。mov DWORD PTR [eax], OFFSET ??_7B@@6B@
其中eax存放了this指针,??_7B@@6B表示B::`Vftable即B类的虚函数表地址。
显然,这句将D类的虚函数表指针改为了B的虚函数表地址。
所以,第二次调用:
通过B的虚函数索引到的,是B::~B() ,打印“B”;
第三次调用:
直接调用D::~D() ,因为这里没有通过指针或者引用调用,所以编译器直接生成CALL D::~D(); 打印 “D” 和“B”。
GCC和MSVC可以得到相同的结果,析构函数会将虚函数表指针修改为指向其对应类的虚函数表,这点不知道C++标准有没有的条款,LZ有兴趣可以查一下。
int main(int, char * [])
{
B * b = new D;
b->~B();
std::cout << "---" << std::endl;
delete b; // why?
std::cout << "---" << std::endl;
return(0);
}
我解释不清楚为什么第二次的多态现象没了