复制构造函数和组合

时间:2012-01-07 17:05:46

标签: c++ copy-constructor

我有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是抽象类

2 个答案:

答案 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;
}