我知道虚拟表会在调用类析构函数之前自动更新,所以我想到了检查对象类型信息会发生什么。我写了这个例子:
#include <iostream>
class Base {
public:
Base(std::function<void(Base*)> callback) : _callback(callback) {}
virtual ~Base() {
_callback(this);
}
std::function<void(Base*)> _callback;
};
class Derived : public Base {
using Base::Base;
};
int main() {
auto check_type = [](Base* item) {
if (dynamic_cast<Derived*>(item)) {
std::cout << "is derived" << std::endl;
} else {
std::cout << "no derived" << std::endl;
}
};
Derived derived(check_type);
check_type(&derived);
return 0;
}
并基于输出:
is derived
no derived
似乎clang-802.0.41更新了此记录。现在我想知道这是标准化的还是编译器特定的?
答案 0 :(得分:3)
使用dynamic_cast
在构造函数或析构函数中不起作用。在Base::Base
期间,您还没有执行派生类型的构造函数。同样,到达Base::~Base
时,派生类型的析构函数必须已经完成。在这两种情况下,您的实例都不是有效的Derived
对象。
来自http://en.cppreference.com/w/cpp/language/dynamic_cast#Explanation
6)当在构造函数或析构函数中(直接或间接)使用dynamic_cast时,表达式引用当前正在构造/销毁的对象,该对象被认为是派生最多的对象。 如果new_type不是构造函数/析构函数自己的类或其基础之一的指针或引用,则行为未定义。
答案 1 :(得分:0)
如果dynamic_cast的操作数引用了下面的对象 构造或破坏以及操作数的静态类型不是 指向构造函数或析构函数自己的类或对象的指针 作为其基础之一,dynamic_cast导致未定义的行为。
this
不是指向Base
自己的类的指针,也不是指向其中一个基础的指针,因此您有未定义的行为。