从void *转换为基类的指针
我有一些层次结构:基类,派生类和一些将用户数据存储为void *的结构。 该void可以存储Base和Derived类指针。 主要的问题是我不知道存储在那里的基础或派生指针。
class Base
{
public:
int type;
};
class Derived: public Base
{};
Base* base;//init base pointer
Derived* derived;//init derived pointer
void* base_v = base;
void* derived_v = derived;
//void pointers are correct. They point to base and derived variables.
//try to get type field after converting pointers back
Derived* d_restored = (Derived*)derived_v;//d_restored correct
Base* b_restored = (Base*)base_v;//b_restored correct
Base* d_restored_to_base = (Base*)derived_v;// INCORRECT
如何将void *转换为两个指针的[type]字段? 提前致谢。
void*
只能转换回原来的类型。 将Derived*
存储在void*
,只能转回Derived*
, 而不是 Base*
。
这对于多重继承尤其明显,因为您的派生对象可能不一定与您的基地址在同一地址。 如果你确实需要用void*
存储事物(并检索事物),那么总是先投射到基类型,这样你就有了一种稳定的方法来获取对象:
#include <iostream>
struct base { int type; };
struct intruder { int iminyourclassstealingyourbase; };
struct derived : intruder, base {};
int main()
{
derived d; d.type = 5;
void* good = (base*)&d;
void* bad = &d;
base* b1 = (base*)good;
base* b2 = (base*)bad;
std::cout << "good: " << b1->type << "n";
std::cout << "bad: " << b2->type << "n";
}
如果您然后想要返回派生类型,请使用dynamic_cast
(或static_cast
如果您保证它必须是派生类型)。
当你使用多重继承时,结果对象的内部行为很像复合,概念上是这样的:
struct Derived {
Base1 b1;
Base2 b2;
};
根据是否将其转换为Base1或Base2,您将获得Derived实例的不同地址。 所以,你不能可靠地做你想做的事情。 您需要保留指向其中一个涉及类型的指针,并使用dynamic_cast
或者,您可以制定自己的规则 - 说您始终将实例的地址存储到特定的基类中,并始终将其重新投递到此基类。 这很容易出错,我强烈建议你尽可能地存储一个指向公共基类的指针。
如果你知道它是一个派生指针并且你想获得一个基指针,你可以这样做:
Base* d_restored_to_base = (Base*)(Derived*)derived_v;
您会发现Base *指向与Derived *不同的位置,因此中间转换是必需的。
链接地址: http://www.djcxy.com/p/43837.html