我有A级和B级之间的组合关系,
class A
{
A(); //default constructor //EDIT
A(const A &mA); // copy constructor //EDIT
virtual ~A();
};
class B
{
B(A *pA); //constructor
B(const B &mB) //copy constructor
virtual ~B(); //EDIT: destructor to eliminate mA and to build the composition
A* mA;
};
我可以用这种方式编写复制构造函数:
B(const B &mB, A *pA)
我需要它来保持复制对象之间的构图。 这是错的吗?它是否存在更好的解决方案? 谢谢
编辑:我会试着更好地解释一下。我想要一个对象mB和对象mA的副本。但是如果在复制构造函数中我写了mA = mB.mA,我会将地址复制到原始对象mA。所以我认为我需要一个深拷贝而不是燕子拷贝。我的困惑是因为现在,从主要的,我首先复制对象mA然后我复制mB。这样做,我想我需要将复制的对象mA分配给外部函数,如foo(A *pA)
否则,如果我可以执行mB的深层复制,我可以解决问题。这被称为深层复制吗?
P.S。 A和B是抽象类
答案 0 :(得分:6)
没有。根据定义,复制构造函数不能具有您所描述的签名。以下是复制构造函数的一些有效签名:
B(const B &);
B(B &); // Thanks Oli!
你为什么需要它?您可以通过执行类似的操作来访问复制构造函数中的mA成员(我可能已经犯了一些语法错误):
B::B(const B & original)
{
mA = original.mA;
}
答案 1 :(得分:0)
你可能会过度思考这个问题。复制构造函数只需要将所有成员初始化为源对象的相应值,例如,像这样:
B(B const & rhs) : mA(rhs.mA) { }
这只是一个简单的副本,所以如果没有别的东西,那么你最好不要写任何拷贝构造函数。
另一方面,如果你想要一个深副本,它可能是这样的:
B(B const & rhs) : mA(::new A(rhs.mA)) { }
但是,详细信息取决于类B
的实际所有权政策与指针mA
的关系。根据这些细节,如果需要,不要忘记编写适当的析构函数。
您还应该编写复制构造函数的匹配赋值运算符,这样做非常重要,例如:
B & operator=(B const & rhs)
{
if (this != &rhs)
{
A * tmp = ::new A(*rhs.mA); // need try/catch in general!
::delete mA; // OK, no exception occurred if we got here
mA = tmp;
}
return *this;
}