用于验证类型的动态转换
Dynamic cast used for validating type
为了避免 X Y 情况,我正在尝试验证 void*
指针转换是否有效。
为了解决这个问题,我想使用 dynamic_cast
的属性。
给定以下代码:
class A
{
virtual void foo(){}
};
class B
{
virtual void bar(){}
};
void* createA() { return new A();}
void* createB() { return new B();}
int main()
{
A* ptr =reinterpret_cast<A*>(createA());
A* ptr2 = reinterpret_cast<A*> (createB());
ptr = dynamic_cast<A*>(ptr); // not NULL as expected
ptr2 = dynamic_cast<A*> (ptr2); // was expecting NULL, however it's a valid pointer
}
如果 RTTI 不是预期的类型,dynamic_cast 不应该以 NULL 失败吗?
通常解决此类问题的方法是给A
和B
一个公共标签库class/interface。 void*
不保留任何类型信息。 reinterpret_cast<>
也会简单地覆盖任何可能存在的类型信息。
你可以这样做:
class Base {
public:
virtual ~Base() {}
};
class A : public Base
{
virtual void foo(){}
};
class B : public Base
{
virtual void bar(){}
};
Base* createA() { return new A();}
Base* createB() { return new B();}
int main()
{
Base* ptr = createA();
Base* ptr2 = createB();
ptr = dynamic_cast<A*>(ptr); // not NULL as expected
ptr2 = dynamic_cast<A*> (ptr2); // NULL pointer now
}
dynamic_cast
不能用于检查指向任意内存地址的指针是否指向特定类型的对象。 dynamic_cast
将仅在该对象的类型可能位于要转换为的类型的继承链中的情况下,通过检查所指向对象的 RTTI 来执行转换。在您的示例中,将 B *
转换为 A *
将始终产生 nullptr,即使 B *
实际上指向 A
:
A * a_ptr = dynamic_cast<A*>(reinterpret_cast< B* >(createA()));
assert(nullptr == a_ptr);
此外,您正在尝试将 A *
转换为 A *
,这基本上会导致 noop:
5.2.7 Dynamic cast [expr.dynamic.cast]
3 If the type of v is the same as T , or it is the same as T except that the class object type in T is more cv-qualified than the class object type in v, the result is v (converted if necessary).
为了避免 X Y 情况,我正在尝试验证 void*
指针转换是否有效。
为了解决这个问题,我想使用 dynamic_cast
的属性。
给定以下代码:
class A
{
virtual void foo(){}
};
class B
{
virtual void bar(){}
};
void* createA() { return new A();}
void* createB() { return new B();}
int main()
{
A* ptr =reinterpret_cast<A*>(createA());
A* ptr2 = reinterpret_cast<A*> (createB());
ptr = dynamic_cast<A*>(ptr); // not NULL as expected
ptr2 = dynamic_cast<A*> (ptr2); // was expecting NULL, however it's a valid pointer
}
如果 RTTI 不是预期的类型,dynamic_cast 不应该以 NULL 失败吗?
通常解决此类问题的方法是给A
和B
一个公共标签库class/interface。 void*
不保留任何类型信息。 reinterpret_cast<>
也会简单地覆盖任何可能存在的类型信息。
你可以这样做:
class Base {
public:
virtual ~Base() {}
};
class A : public Base
{
virtual void foo(){}
};
class B : public Base
{
virtual void bar(){}
};
Base* createA() { return new A();}
Base* createB() { return new B();}
int main()
{
Base* ptr = createA();
Base* ptr2 = createB();
ptr = dynamic_cast<A*>(ptr); // not NULL as expected
ptr2 = dynamic_cast<A*> (ptr2); // NULL pointer now
}
dynamic_cast
不能用于检查指向任意内存地址的指针是否指向特定类型的对象。 dynamic_cast
将仅在该对象的类型可能位于要转换为的类型的继承链中的情况下,通过检查所指向对象的 RTTI 来执行转换。在您的示例中,将 B *
转换为 A *
将始终产生 nullptr,即使 B *
实际上指向 A
:
A * a_ptr = dynamic_cast<A*>(reinterpret_cast< B* >(createA()));
assert(nullptr == a_ptr);
此外,您正在尝试将 A *
转换为 A *
,这基本上会导致 noop:
5.2.7 Dynamic cast [expr.dynamic.cast]
3 If the type of v is the same as T , or it is the same as T except that the class object type in T is more cv-qualified than the class object type in v, the result is v (converted if necessary).