gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 01:06:45 25 4
gpt4 key购买 nike

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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com