【发布时间】:2021-11-02 00:59:37
【问题描述】:
我有一种情况,我想在调用函数的另一个调用之后导入一个调用。为此,我决定重写一个虚拟析构函数:
#include <iostream>
struct type {
virtual ~type() {
std::cout << "ordinary" << std::endl;
}
void method() {
struct method_called : type {
virtual ~method_called() override {
std::cout << "method called" << std::endl;
}
};
this->~type();
new (this) method_called{};
}
};
int main() {
std::cout << "ordinary expected" << std::endl;
{
type obj;
}
std::cout << "method expected" << std::endl;
{
type obj;
obj.method();
}
std::cout << "method expected" << std::endl;
type* pobj = new type{};
pobj->method();
delete pobj;
}
似乎只使用动态分配调用了被覆盖的析构函数。这是故意的吗?
【问题讨论】:
-
在调用
this->~type()之后,this的使用具有未定义的行为。您的代码不会以某种方式将type的实例变形为(本地定义的)method_type的实例,这(似乎是)您正在尝试做的事情。 -
obj.method();不会更改obj类型。这仍然是type。编译器在}之后直接调用析构函数type::~type,而不是使用vtbl,因为它知道obj的类型。 -
@Peter 我仍然不相信 - 你能写一个答案吗?可能引用标准。或者如果有的话,可以链接另一个类似的问题。
-
@AnArrayOfFunctions 尽管有太多的语言律师暗示并非如此,但该标准并未详细说明未定义行为的每个实例。有很多情况下,行为是由于遗漏而未定义的——即标准没有对发生的事情指定任何约束。那是因为标准委员会成员只是没有预料到这种用法的凡人(如果没有人预料到尝试执行 X 的代码,则不可能指定由于此类尝试而发生的限制,同样不可能指定没有约束,即使其未定义)。
标签: c++ inheritance polymorphism virtual destructor