Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 关于复制包含不可复制成员引用的类的构造函数的建议_C++_Copy Constructor_Private Constructor_Default Copy Constructor - Fatal编程技术网

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

C++ 关于复制包含不可复制成员引用的类的构造函数的建议,c++,copy-constructor,private-constructor,default-copy-constructor,C++,Copy Constructor,Private Constructor,Default Copy Constructor,我有一个类a,它作为成员引用了类B的对象。类B的复制构造函数(和赋值运算符)是私有的。你认为这是一个有效的好主意吗 A的默认复制构造函数。(实际上,我需要一个功能,可以将A类型的大量对象存储在某种STL容器中,该容器既需要赋值能力,也需要复制能力。) 到目前为止,据我所知,反对上述方法的理由如下,但我的设计没有面对它。我想知道上述示例是否存在其他问题/问题/顾虑 只有引用被复制,因此,当类型b的原始对象b被销毁时会出现问题。(不适用,因为b在整个范围内都可用。) b_uu对于A的每个实例都是唯一

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

到目前为止,据我所知,反对上述方法的理由如下,但我的设计没有面对它。我想知道上述示例是否存在其他问题/问题/顾虑

  • 只有引用被复制,因此,当类型b的原始对象b被销毁时会出现问题。(不适用,因为b在整个范围内都可用。)
  • b_uu对于A的每个实例都是唯一的吗?(不,B实际上在作用域中只实例化一次,因此它具有单例类的效果。)
  • 如果还有其他问题,请在此处列出。我不喜欢显式定义的复制构造函数,但我对它持开放态度

    检查

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

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


    作为补充说明,我确实建议将
    a(B&)
    构造函数显式化,以避免隐式地将
    B
    视为
    a

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

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

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

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

    如果B的赋值运算符是私有的,则编译器无法为a生成默认的a赋值运算符。您必须显式声明赋值运算符。否则会出现编译错误:


    一旦这样做了,将对象A放入STL容器应该没有问题。

    A
    不是默认可构造的,因此不能在标准容器中使用它。A不需要默认可构造才能在任何STL容器中使用。您只需要c语言的默认构造函数-array@Alessandro:非常有趣,我一直认为这是一个要求!这种情况在C++0x中发生了变化,还是一直如此?(这就是说,OP的
    A
    不能被复制或移动构造,因此它不能在标准容器中使用。)@Kerrek:一些构造函数和成员函数使用
    t()
    作为默认参数,而那些当然需要默认构造。
    map::operator[]
    也是如此,它默认构造值类型。除此之外(以及我已经忘记的任何其他具体用途),它并没有作为一项要求进行说明。23.1/3说明了什么的一般要求?C++标准2003?OHK…隐马尔可夫模型。。。我想要一个赋值操作符,不管怎样。。。所以我想我会写一个。。谢谢……我看到了链接。。。我不确定这是不是一回事。。。我会尝试一下代码,让你知道会发生什么。。。。。。如果没有默认的赋值运算符。。我想我会实现的……但是B是不可复制的。。。我该如何定义赋值运算符?对不起,我弄错了,我想我看错了你的问题,提出了一个不同的问题(你可以从上面的链接中看到)。由于您的既不是从B继承,也不是直接持有B对象,而是持有对B对象的引用,因此默认的复制构造函数应该可以做到这一点。但请注意,引用语法意味着类A不拥有B.btw。。。我想我已经让构造函数显式了。。。。你想说它应该更明确吗?如果是。。那怎么办?
    class A
    {
        B* b; // or a smart pointer, depending on what semantics you want.
    
    public:
        A(B& b) : b(&b) {}
    };