views:

221

answers:

3

This is just a quick question to understand correctly what happens when you create a class with a constructor like this:

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

I know that no default constructor is generated since it is already defined but are copy and assignment constructors generated by the compiler or in other words do i need to declare a private copy constructor and a private assignment operator in order to prevent this from happening?

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

Yes. The copy constructor, assignment operator, and destructor are always created regardless of other constructors and operators.

If you want to disable one, what you've got there is perfect. It's quite common too.

GMan
+10  A: 

Yes, copy constructor and copy assignment operators are still created even if you declare your own default constructor.

The creation of those are only suppressed if you declare your own copy constructor or copy assignment operator in the class definition respectively.

Note that it is possible to have both your own copy constructor, and a compiler provided one:

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!
}

The Standard however allows compilers to accept this code - but the effect is similar to having undefined behavior: The program is ill-formed, but no warning/error is required for that program. (early GCC versions don't reject this code, recent ones reject it).

Johannes Schaub - litb
Your posts are "as usual" very informative :)
Prasoon Saurav
You just *had* to add something over mine, eh. :]
GMan
+1  A: 

If you want to disable copying and assigning, then it might be better to inherit from a class that has a private copy constructor and assignment operator (boost::noncopyable is a ready-made one).

1) Less repetitive typing.

2) Self-documenting (hopefully).

3) Stronger checks that those operations can't be invoked (the class itself, nor the friends can make copies either - that would result in a compiler, not a linker error).

4) Won't hide the default constructor :)

#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
}
UncleBens