c – 从空白中进行演员的运行时检查*
假设我有一个包含指向未知类的指针的void *.我想使用dynamic_cast对我实际拥有的类的类型进行运行时检查.例如:
class Foo {}; void* bar = new Foo; 如果我尝试做dynamic_cast< Foo *>(bar),我得到:
但是我需要dynamic_cast,因为在我的实际情况中,我不确定bar实际上是Foo *. 我已经阅读了here,其中一个解决方案是为bar可以包含的所有对象创建一个基类,将reinterpret_cast重新指定为指向该基类的指针,然后尝试从该对象指向dynamic_cast到Foo. 这对我来说很难,因为可能存储在栏中的对象并非都在我的控制之下. (并且导致尝试重新创建Java让我心痛.)还有另一种方法吗? 解决方法
dynamic_cast用于将多态对象转换为类,该类具有您尝试将其作为父对象的类型.
void *与此完全不同. dynamic_cast知道有一个基类,可以通过RTTI进行类型检查. 当你施放下一个空指针,你说的编译器:“是啊,你知道在存储这个地方好,用它作为这种类型的?”,如果内存是无效的,UB被调用. 你有三个选择. 选项1 struct Base { virtual ~Base() = default; }; struct Derived : Base {}; // ... void test (Base* base) { auto derived = dynamic_cast<Derived*>(base); if (derived) { // derived is valid here. } } 选项2 using type_id_t = void(*)(); template <typename T> void type_id() {} // now we can use a map or a vector. std::vector<std::pair<type_id_t,void*>> vec; template<typename T> void insertToMyVector(T* obj) { vec.emplace_back(type_id<T>,obj); } template<typename T> T* getObj(int index) { auto item = vec[index]; return static_cast<T*>(item.first == &type_id<T> ? item.second : nullptr); } // ... int main () { auto foo = new Foo; insertToMyVector(foo); auto maybeFoo = getObj<Foo>(0); if (maybeFoo) { // you have a valid Foo here } } 选项3 struct Base { virtual ~Base() = default; }; template<typename T> struct Derived : Base { Derived(T&& obj) : _obj{std::move(obj)} {} Derived(const T& obj) : _obj{obj} {} T& get() { return _obj; } const T& get() const { return _obj; } private: T _obj; }; // ... void test (Base* base) { auto derived = dynamic_cast<Derived<int>*>(base); if (derived) { int i = derived->get(); // derived is valid here,and we can safely access the int } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |