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

Advice on Copy Constructor of a Class containing a non-copyable member reference

本文关键字:复制 构造函数 引用 于包含 可复制 成员      更新时间:2023-10-16

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

class A
{
    private:
        B& b_;
    public:
        A(B& b) : b_(b){}
}

到目前为止,据我所知,上述方法的反对意见如下,但我的设计并没有面对它。我想知道关于上面的例子是否还有其他问题/问题/担忧……

  1. 只有引用被复制,因此,当b类型的原始对象b被销毁时会出现问题。(不适用,因为b在整个范围内可用。)
  2. b_对于A的每个实例都是唯一的吗?(不,B实际上只在作用域中实例化一次,所以它具有单例类的效果。)

如果还有其他问题,请在这里列出。我不热衷于明确定义的复制构造函数,但我对它保持开放的心态。

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

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

class A
{
    B* b; // or a smart pointer, depending on what semantics you want.
public:
    A(B& b) : b(&b) {}
};

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

检查三原则
如果你需要重载这些(析构函数,复制构造函数&复制赋值操作符)3,你需要重载它们。如果你不重载这些函数,那么你可以依赖编译器生成的默认函数。

您不是按值存储B,并且您了解生命周期问题(无论是否复制它都适用),因此我认为使用默认复制构造函数是可以的。

作为旁注,我建议显式地使用A(B&)构造函数,以避免隐式地将B视为A

如果B的赋值操作符是私有的,则编译器不能为a生成默认的赋值操作符,必须显式声明一个赋值操作符。否则你得到一个编译错误: http://msdn.microsoft.com/en-us/library/aa983787%28v=vs.71%29.aspx

一旦你这样做了,你应该没有问题把对象A到STL容器