Answers:
dynamic_cast应该可以解决问题
TYPE& dynamic_cast<TYPE&> (object);
TYPE* dynamic_cast<TYPE*> (object);
该dynamic_cast
关键字从一个指针或引用类型转换基准到另一个,执行运行时检查以确保铸造的有效性。
如果您尝试将指针转换为非实际对象类型的指针,则转换结果将为NULL。如果您尝试强制转换对不是实际对象类型的类型的引用,则强制转换将引发bad_cast
异常。
确保在基类中至少有一个虚函数使dynamic_cast工作。
维基百科主题运行时类型信息
RTTI仅适用于多态类,这意味着它们具有至少一个虚拟方法。实际上,这不是一个限制,因为基类必须具有虚拟析构函数,以允许如果将派生类的对象从基体指针中删除,则它们可以执行适当的清除操作。
dynamic_cast
如果它不可转换,不会抛出吗?有没有办法做到而又不会产生抛出的方法?
A* aptr = dynamic_cast<A*>(ptr);
//是否应该是这样
uint8_t*
吗?也就是说,我可以检查uint32_t* x = dynamic_cast<uint32_t*>(p)
,在那里p
是uint8_t*
?(我正在尝试查找违反礼节的测试)。
动态类型转换最适合描述问题,但是我只想补充一下,您可以使用以下方法找到类类型:
#include <typeinfo>
...
string s = typeid(YourClass).name()
11MyClass
。要取消破坏,可以使用中的ABI扩展库cxxabi.h
。这给了您abi::__cxa_demangle
真实的名字
这称为RTTI,但是您几乎肯定要在这里重新考虑设计,因为找到类型并基于它执行特殊操作会使您的代码更脆弱。
为了完整起见,我将构建Robocide的构建,并指出typeid
无需使用name()即可单独使用:
#include <typeinfo>
#include <iostream>
using namespace std;
class A {
public:
virtual ~A() = default; // We're not polymorphic unless we
// have a virtual function.
};
class B : public A { } ;
class C : public A { } ;
int
main(int argc, char* argv[])
{
B b;
A& a = b;
cout << "a is B: " << boolalpha << (typeid(a) == typeid(B)) << endl;
cout << "a is C: " << boolalpha << (typeid(a) == typeid(C)) << endl;
cout << "b is B: " << boolalpha << (typeid(b) == typeid(B)) << endl;
cout << "b is A: " << boolalpha << (typeid(b) == typeid(A)) << endl;
cout << "b is C: " << boolalpha << (typeid(b) == typeid(C)) << endl;
}
输出:
a is B: true
a is C: false
b is B: true
b is A: false
b is C: false
使用重载函数。不需要dynamic_cast甚至RTTI支持:
class A {};
class B : public A {};
class Foo {
public:
void Bar(A& a) {
// do something
}
void Bar(B& b) {
Bar(static_cast<A&>(b));
// do B specific stuff
}
};
如果可以访问boost库,则可能需要使用type_id_with_cvr()函数,该函数可以提供数据类型而无需删除const,volatile和&&&&修饰符。这是C ++ 11中的一个简单示例:
#include <iostream>
#include <boost/type_index.hpp>
int a;
int& ff()
{
return a;
}
int main() {
ff() = 10;
using boost::typeindex::type_id_with_cvr;
std::cout << type_id_with_cvr<int&>().pretty_name() << std::endl;
std::cout << type_id_with_cvr<decltype(ff())>().pretty_name() << std::endl;
std::cout << typeid(ff()).name() << std::endl;
}
希望这是有用的。