2

我有一个 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 实际上只在作用域中实例化一次,因此它具有单例类的效果。)

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

4

4 回答 4

2

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

于 2011-07-27T16:00:18.727 回答
2

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

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

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

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

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

于 2011-07-27T16:03:37.317 回答
0

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

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

于 2011-07-27T16:03:07.590 回答
0

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

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

于 2011-07-27T16:13:08.830 回答