直到今天,我还以为如果我的类A
和B
没有任何关联,那么使用指针的dynamic_cast
将无法返回nullptr
。现在我读到这会导致不确定的行为...
cppreference - dynamic_cast:
我有这样的代码:
class ActorComponent
{
ActorComponent* m_parent;
public:
template <typename _type>
_type* getParent() const {
return dynamic_cast<_type*>(m_parent);
}
ActorComponent(ActorComponent* parent) {
// using `getParent` inside the constructor:
auto p = this->getParent<int>(); // `int` obviously isn't base of the ActorComponent
}
};
我需要限制
_type
键入以下任一类型ActorComponent
ActorComponent
...甚至更多。
问题是:如何确保在编译时将
dynamic_cast
转换为此类_type
不会导致未定义的行为?会简单吗template <typename _type,
typename = std::enable_if_t< std::is_base_of_v<ActorComponent, std::remove_cv_t<_type> > || std::is_same_v<ActorComponent, std::remove_cv_t<_type> > >
一直在工作?
最佳答案
tl; dr 很好。由于某种原因,您在显然不适用于您的代码的条件下选择了代码。
您的报价:
显然是关于在构造函数或析构函数中使用dynamic_cast
的信息,尽管出于某些原因,您省略了完整的上下文:
由于您没有在构造函数或析构函数中使用它,因此情况6显然无关紧要。
与您的代码实际相关的情况是:
检查稍后编辑的代码:
ActorComponent(ActorComponent* parent) {
// using `getParent` inside the constructor:
// `int` obviously isn't base of the ActorComponent
auto p = this->getParent<int>();
}
第6条的条件的第一部分
被满足(
getParent
代码在构造函数中间接存在),但是第二部分:不满意,因此第6条仍然不适用。
您正在转换
m_parent
,它是您正在构造的ActorComponent
对象的成员子对象。由于成员子对象是在您进入构造函数的主体时完全构造的,因此该对象未被构造,并且我们不在该对象的构造函数中。除了其他内容外,该对象(m_parent
)是一个指针,没有构造函数。顺便说一句,它是未初始化的,因此您的代码无论如何都是完全非法的,但并非出于您询问的原因。关于c++ - 确保dynamic_cast不会导致未定义的行为C++,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49038905/