关于包含不可复制成员引用的类的复制构造函数的建议

时间:2011-07-27 15:56:29

标签: c++ copy-constructor private-constructor default-copy-constructor

我有一个A类,它引用了B类对象作为成员。 B类的复制构造函数(和赋值运算符)是私有的。你认为这是一个有效和好主意使用 A的默认复制构造函数。(我实际上想要一种功能,我可以在某种STL容器中存储A类的大量对象,这需要赋值和复制能力。)

class A
{
    private:
        B& b_;

    public:
        A(B& b) : b_(b){}
}

到目前为止,据我所知,对上述方法的反对如下,但我的设计并没有面对它。我想知道上述例子是否存在其他一些问题/问题/担忧......

  1. 仅复制引用,因此,当销毁类型B的原始对象b时会出现问题。 (不适用,因为b在整个范围内都可用。)
  2. 对于A的每个实例,b_是唯一的吗? (不,B实际上只在范围内实例化一次,因此它具有单例类的效果。)
  3. 如果还有其他问题,请在此处列出。我并不热衷于明确定义的复制构造函数,但我对此持开放态度。

4 个答案:

答案 0 :(得分:2)

检查 Rule of Three 如果你需要重载其中任何一个(析构函数,复制构造函数和复制赋值运算符)三,你需要重载所有这些。如果你没有重载任何这些,那么你可以依赖编译器生成的默认函数。

答案 1 :(得分:2)

作为一般准则,我从不在对象中存储引用,因为我无法免费获得复制语义。

我存储了指针。在这里,存储一个哑指针并让编译器为你实现复制语义似乎很好:

class A
{
    B* b; // or a smart pointer, depending on what semantics you want.

public:
    A(B& b) : b(&b) {}
};

使用指针具有一定的灵活性:例如,默认构造可以将指针设置为零,后续操作会检查其有效性(或简单地assert)。此外,指针可以重置,而引用则不是这样。

答案 2 :(得分:0)

您没有按值存储B并且您了解终身问题(无论是否复制它们都适用)所以我认为使用默认的复制构造函数很好。

作为旁注,我建议明确A(B&)构造函数,以避免隐含地将B视为A

答案 3 :(得分:0)

如果B的赋值运算符是私有的,则编译器无法为A生成默认的赋值运算符。您必须显式声明赋值运算符。否则你会遇到编译错误http://msdn.microsoft.com/en-us/library/aa983787%28v=vs.71%29.aspx

完成后,您应该没有问题将对象A放入STL容器中。