【发布时间】:2014-03-05 09:40:18
【问题描述】:
我有一个 C++ 类,其中包含具有指向类中其他对象的引用成员的对象。这在当时似乎是个好主意,但现在我需要实现整个事情的深层副本,而且我找不到一种方法来做这件事,感觉不像是笨拙的 hack。
我的代码的简化版本如下所示。问题是关于为A 编写一个复制构造函数。
class C {
int x, y, z; // nothing complicated stored in this class
public:
// constructor and other methods
};
class B {
C &c1;
C &c2;
public:
// constructor and other methods
};
class A {
C *c_array;
B *b_array; // for each item in this array,
// its 'c1' and 'c2' fields point to members of c_array.
public:
// constructor and other methods
};
有些人问这个结构是如何初始化的,所以请让我强调一下,这与回答问题无关。初始化将始终满足b_array 中项目的引用成员指向c_array 中的项目的要求,但除此之外,数据可以是任何东西。复制构造函数适用于满足此属性的任何数据是很重要的。这不是可以通过重用现有初始化代码来解决的问题。
问题是,如果我只是复制b_array 中的对象,它们的引用成员将指向A 的old 实例中的C 对象。我需要让它们指向 new 实例中的相应项目。我能想到的唯一方法是:
对于
b_array的每个元素,获取其引用成员指向的地址,并将其存储在指针中使用指针算法计算出该指针对应的数组索引
使用该索引初始化新
b_array的对应元素的引用成员。
我的问题是,有没有更清洁/更简单/更优雅的方式?如果没有,我将重构我的设计以使用数组索引而不是整个引用。
也许我不应该使用引用成员 - 我知道有些人说使用指针总是更好。如果我使用指针而不是引用,会有更好的解决方案吗? (我看不到但我不知道。)
【问题讨论】:
-
有趣的问题!我见过的所有“深拷贝”问题都具有在编译时已知的参考结构并在复制逻辑中硬编码。
-
你能把 b_array 和 c_array 都替换成一个 map
吗? -
@GrahamGriffiths 我实际的
B类存储了对c_array成员的多个引用。我想它可以实现为几个map<int,C>s,但真正的B是一个实现其他代码的类层次结构,所以重构会有点棘手。 (我也倾向于避免使用 STL 代码,我想这主要是出于习惯。) -
没有看到您当前如何初始化这些数组,很难给出任何具体建议
-
复制构造函数需要初始化副本,并且您有一些现有的代码来初始化原始文件。所有重要的细节都在 cmets 中以点点滴滴的形式出现,这使得很难猜测解决方案需要提供什么,或者它可以重用哪些现有(未显示)代码