12

这只是一个快速的问题,可以正确理解当您使用这样的构造函数创建类时会发生什么:

class A
{
  public:
    A() {}
};

我知道没有生成默认构造函数,因为它已经定义但是是由编译器生成的复制和赋值构造函数,或者换句话说,我是否需要声明一个私有复制构造函数和一个私有赋值运算符以防止这种情况发生?

class A
{
  private:
    // needed to prevent automatic generation?
    A( const A& );
    A& operator=( const A& );
  public:
    A() {}
};
4

3 回答 3

15

是的,即使您声明了自己的默认构造函数,仍然会创建复制构造函数和复制赋值运算符。

仅当您分别在类定义中声明自己的复制构造函数或复制赋值运算符时,才会禁止创建它们。

请注意,您可以同时拥有自己的复制构造函数,并且编译器提供了一个:

struct A {
  A() { }
  A(A const&, int foo); 
}; // compiler declares a copy constructor now

// make the second parameter have a default argument
// now this constructor is a copy constructor too. 
inline A::A(A const&, int foo = 0) {

}

int main() {
  A a;
  A b = a; // ambiguity between compiler's one and our custom one!
}

然而,该标准允许编译器接受此代码 - 但效果类似于具有未定义的行为:程序格式错误,但该程序不需要警告/错误。(早期的 GCC 版本不拒绝此代码,最近的版本拒绝它)。

于 2010-03-04T16:10:46.350 回答
14

是的。无论其他构造函数和运算符如何,始终会创建复制构造函数、赋值运算符和析构函数。

如果您想禁用一个,那么您所拥有的就是完美的。这也很常见。

于 2010-03-04T16:10:30.577 回答
3

如果要禁用复制和分配,那么最好从具有私有复制构造函数和赋值运算符的类继承(boost::noncopyable是现成的)。

1) 减少重复输入。

2)自我记录(希望如此)。

3) 更严格地检查这些操作不能被调用(类本身,也不能制作副本——这将导致编译器错误,而不是链接器错误)。

4) 不会隐藏默认构造函数:)

#include <boost/noncopyable.hpp>

class X : boost::noncopyable
{
};

int main()
{
    X a, b;     //has default constructor
    //X c(a);   //but can't be copied
    //a = b;    //or assigned
}
于 2010-03-04T21:02:02.267 回答