C++如何深度复制具有未知数据类型的结构?

1 c++ constructor types subclass

我有一个"数据提供者",它将其输出存储在某种类型的结构中

struct DATA_TYPE1{
   std::string data_string;
};
Run Code Online (Sandbox Code Playgroud)

那么这个结构必须被转换成一般的数据类型,我想到了void*或char*,因为将它复制并存储在二叉树中的"中间"对象应该能够存储许多不同类型的这种结构数据.

struct BINARY_TREE_ENTRY{
   void * DATA;
   struct BINARY_TREE_ENTRY * next;
};
Run Code Online (Sandbox Code Playgroud)

然后,此void*由另一个将void*转换回(struct DATA_TYPE1*)以获取原始数据的对象获取.所以发件人和收件人都知道数据类型DATA_TYPE1,而不知道中间的复制对象.

但是,当不知道数据类型时,中间对象如何深层复制不同结构的内容,只有void*并且它没有复制真实内容的方法; dynamic_cast不适用于void*;

"中间"对象应该做的事情如下:

void store_data(void * CASTED_DATA_STRUCT){
   void * DATA_COPY = create_a_deepcopy_of(CASTED_DATA_STRUCT);
   push_into_bintree(DATA_COPY);
}
Run Code Online (Sandbox Code Playgroud)

一个简单的解决方案是发送对象不会删除发送的数据结构,直到接收对象获得它,但是在接收者从中间对象获取数据之前动态创建和删除发送对象,以进行异步通信,因此我想复制它.

而不是将其转换为void*我也尝试转换为中间复制对象知道的超类指针,并且由结构的所有不同数据类型继承:

struct DATA_BASE_OBJECT{
public:
    DATA_BASE_OBJECT(){}
DATA_BASE_OBJECT(DATA_BASE_OBJECT * old_ptr){
         std::cout << "this should be automatically overridden!" << std::endl;
    }
    virtual ~DATA_BASE_OBJECT(){}
};

struct DATA_TYPE1 : public DATA_BASE_OBJECT {
public:
    string str;
    DATA_TYPE1(){}
    ~DATA_TYPE1(){}
    DATA_TYPE1(DATA_TYPE1 * old_ptr){
         str = old_ptr->str;
    }
};
Run Code Online (Sandbox Code Playgroud)

然后相应的二进制树条目将是:

struct BINARY_TREE_ENTRY{
       struct DATA_BASE_OBJECT * DATA;
       struct BINARY_TREE_ENTRY * next;
    };
Run Code Online (Sandbox Code Playgroud)

然后复制未知数据类型,我尝试在类中获取未知数据类型作为结构DATA_BASE_OBJECT*(在它之前是void*):

void * copy_data(DATA_BASE_OBJECT * data_that_i_get_in_the_sub_struct){
     struct DATA_BASE_OBJECT * copy_sub = new DATA_BASE_OBJECT(data_that_i_get_in_the_sub_struct);
     push_into_bintree(copy_sub);
}
Run Code Online (Sandbox Code Playgroud)

然后我将一个复制构造函数添加到DATA_BASE_OBJECT,但如果结构DATA_TYPE1首先被转换为DATA_BASE_OBJECT然后被复制,则不会复制包含的子对象DATA_TYPE1.

然后我想到找出要复制的实际对象的大小,然后只记忆它,但字节不存储在一行中,我如何找到结构DATA_TYPE1的内存中的实际大小,其中包含std: :串?

哪些其他c ++方法可用于深度检查未知数据类型(并且可能在运行时以其他方式获取数据类型信息)?

小智 9

如果您有void *,则无法从中提取任何类型信息.这就是为什么void *很少,很少用于C++程序(我老实说上不记得上次使用过程) - 你的方法完全错了.如果您想要在编译时知道类型的通用容器,请使用模板.如果您希望类型在运行时变化的容器,则从基类派生并使用基类指针的容器.并且不要编写自己的容器(除了可能作为学习练习) - C++有一个非常好的二叉树实现为std :: set和std :: map.

最后,不要将ALL CAPS用于C++类型的名称.

  • +1用于阻止所有CAPS.我的眼睛!:-D (2认同)