这只是一个快速的问题,可以正确理解当您使用如下构造函数创建类时会发生什么:
class A
{
public:
A() {}
};
我知道没有生成默认构造函数,因为它已经定义但是由编译器生成的复制和赋值构造函数,或者换句话说我需要 声明私有拷贝构造函数和私有赋值运算符以防止这种情况发生?
class A
{
private:
// needed to prevent automatic generation?
A( const A& );
A& operator=( const A& );
public:
A() {}
};
答案 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
}