编译生成的构造函数

时间:2010-03-04 16:07:39

标签: c++ copy-constructor assignment-operator default-constructor

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

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

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

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

3 个答案:

答案 0 :(得分:13)

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

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

请注意,可以同时拥有自己的复制构造函数和编译器:

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版本不拒绝此代码,最近的代码拒绝它)。

答案 1 :(得分:11)

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

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

答案 2 :(得分:2)

如果要禁用复制和分配,那么从具有私有复制构造函数和赋值运算符的类继承可能更好(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
}
相关问题