2

If I declare a class like, (no dynamic memory allocation, no pointer):

class A{
  int a,b;
public:
  A();
  A(int,int);
  A& operator=(const A);
};

Is it safe not to declare a copy constructor? How does the default copy constructor looks like?

A& A::operator=(const A other)
{
   a=other.a;
   b=other.b;
   return *this;
}

Even If I do not declare a copy constructor, the default one will be called when I call operator=()


EDIT:

the default destructor is:

A::~A(){}

so it's not needed here

Cristi
  • 1,195
  • 6
  • 17
  • 24

4 Answers4

6

The rule is that if you need to provide either:

  • copy constructor or
  • destructor or
  • copy assignment operator

then you probably need to provide all three of them. This rule is known as Rule of Three.


Is it safe not to declare a copy constructor?

It is safe.

Do you have to for your example case?

Not really. To be specific the rule of three governs that. Check the linked question for more details on that.


How does the default copy constructor looks like?

I gather this is asking, What does the default copy constructor do.
This is answered in:
C++03 Standard 12.8 Copying class objects:
Para 8:

The implicitly-defined copy constructor for class X performs a memberwise copy of its subobjects. The order of copying is the same as the order of initialization of bases and members in a user-defined constructor (see 12.6.2). Each subobject is copied in the manner appropriate to its type:

— if the subobject is of class type, the copy constructor for the class is used;
— if the subobject is an array, each element is copied, in the manner appropriate to the element type;
— if the subobject is of scalar type, the built-in assignment operator is used.
Virtual base class subobjects shall be copied only once by the implicitly-defined copy constructor (see 12.6.2).


Even If I not declare a copy constructor, the default one will be called when I call operator=()

A copy constructor is invoked only when a copy of the class object needs to be created. This involves copies of objects created while passing to or returning from functions.
Your copy assignment operator passes the object A by value, this pass by value is achieved by passing a copy of the object through copy constructor and hence the call to copy constructor.
To avoid the copy you need to pass by reference:

A& A::operator=(const A& other)

Good Read:
What's the difference between passing by reference vs. passing by value?

Community
  • 1
  • 1
Alok Save
  • 202,538
  • 53
  • 430
  • 533
  • +1, but I don't think that's enough to answer the question. It's obviously important, but I think the question includes "When do I have to provide *any* of the three? Is not having dynamic memory or pointers enough to prove that I don't need any?". – us2012 Feb 07 '13 at 15:03
  • 1
    @us2012: Updated to be more specific. Hth. – Alok Save Feb 07 '13 at 15:17
3

You seem to be confusing copy-constructors with copy-assignment operators. The implicitly generated copy-constructor will copy-construct each of the members:

A::A( A const& source )
  : a( source.a )
  , b( source.b )
{}

The implicitly generated copy-assignment operator will copy-assign each of the members:

A& A::operator =( A const& source )
{
    a = source.a;
    b = source.b;
    return *this;
}

The copy-assignment operator as you defined it in your question takes an A by copy, so the copy-constructor will be called to create the argument passed to operator=. Note that the copy may be elided under certain circumstances.

K-ballo
  • 80,396
  • 20
  • 159
  • 169
1
A::A(const A& other) != A& A::operator=(const A other)
Tim Post
  • 33,371
  • 15
  • 110
  • 174
SeedmanJ
  • 444
  • 2
  • 8
1

Your class provides operator=. Per the rule of three (as @AlokSave says), you should then provide the copy constructor and destructor as well.

The question is, if you're happy with the default-supplied copy constructor, why aren't you happy with the default-supplied copy assignment operator? And if you are, just don't declare operator= and let the compiler generate the entire "rule of three" for you.

Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455