c++ - 一般如何从 void * 指针动态转换?

标签 c++ void-pointers dynamic-cast

class BASE {
public:
    virtual ~BASE() {}
    void lamp() {
        cout << "\nBASE CLASS";
    }
};

class DERIVED : public BASE {
public:
    void fun();
};

void DERIVED::fun() {
    cout << "\nDERIVED CLASS!";
}

int main() {

    BASE * pbase = new DERIVED; //BASE CLASS POINTER
    void * vbase = pbase;       //VOID POINTER TAKING BASE POINTER 
    DERIVED * pder;             //DERIVED CLASS POINTER

    //pder = static_cast<DERIVED *>(vbase);  //THIS WORKS
    pder = dynamic_cast<DERIVED *>(vbase);   //THIS DOESN'T
    pder->lamp();
    pder->fun();

    return 0;
}

每当我尝试将 void* 指针动态转换为派生类指针时,我都会收到以下错误:

cannot dynamic_cast 'vbase' (of type 'void*') to type 'class DERIVED*' (source is not a pointer to class)

我搜索了 StackOverflow 并听从了建议,在基类中实现了一个虚函数以避免错误。我究竟做错了什么? 这可能吗?

我的总体意图是使用 void* 指针将任何传入的对象类型转换为派生类类型。我希望你明白我的意思。

例如:

void dynamicCast(void * vptr)
{
    BASE * pbase = new DERIVED;
    DERIVED * pder;

    pder = dynamic_cast<DERIVED *>(vbase);
}

我应该能够将任何类型的指针传递给 dynamicCast 函数,并且它应该被转换为派生类指针。

最佳答案

我认为存在设计或/和理解问题

如前所述,您不能从 void*dynamic_cast

为什么?因为 dynamic_cast 需要一些运行时类型信息 (RTTI) 来执行转换(更多详细信息请参见 this link)。仅从 void* 来看,C++ 代码没有机会知道此信息在哪里。最低限度是使用指向具有此类 RTTI 信息的对象的指针。

创建此信息并将其绑定(bind)到具有至少一个虚方法 的任何类。如果没有虚拟方法,则不包括此信息。这就是为什么这工作的原因:

struct A
{
};

struct B : A
{
};

int main()
{
  B  b;
  A *a = &b;

  dynamic_cast<B *>(a);  // YOUR COMPILE TIME ERROR
}

解决方法是向 A 添加一个虚拟方法。这里我添加了一个虚拟析构函数作为 this is generally a good thing

struct A
{
   virtual ~A() = default;
};

struct B : A
{
};

int main()
{
  B  b;
  A *a = &b;

  dynamic_cast<B *>(a);  // OK
}

另请注意,dynamic_cast 允许您检查转换是否合法。

例如我们可以添加一个C类并检查:

struct C 
{
};

int main()
{
  B  b;
  A *a = &b;

  assert(dynamic_cast<B *>(a)!=nullptr); // OK
  assert(dynamic_cast<C *>(a)==nullptr); // OK can not cast A to C 
}

这种运行时操作不是免费的。如果你搜索最大速度可以使用这个技巧:

assert(dynamic_cast<B *>(a)!=nullptr);
B* b=static_cast<B*>(a);

在 Debug模式下,您将检查是否一切正常,在 Release模式下,使用 -DNDEBUG 标志来删除 assert 您将只使用 static_cast

关于c++ - 一般如何从 void * 指针动态转换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45950712/

相关文章:

c++ - 如何允许逗号用于基于整数的输入 C++ 的用户输入?

c++ - 将 void 指针转换为结构时无法获取值

C++设计查询

c++ - 在这种情况下,在 'this' 前面加一个星号有什么作用?

C++ 套接字编程 Windows

c++ - 找到OpenCV.cmakeConfig.cmake

c - 在 C 中重新分配 void 指针

c - C代码的指针

c++ - dynamic_cast 的性能

c# - 有没有办法在 C# 中进行动态隐式类型转换?