views:

795

answers:

3

Do we have to explicitly define a default constructor when we define a copy constructor for a class?? Please give reasons.

eg:

class A 
{
    int i;

    public:
           A(A& a)
           {
               i = a.i//Ok this is corrected....
           }

           A() { }   /Is this required if we write the above copy constructor??
};

Also, if we define any other parameterized constructor for a class other than the copy constructor, do we also have to define the default constructor?? Consider the above code without the copy constructor and replace it with

A(int z)
{
    z.i = 10;
}

Alrite....After seeing the answers I wrote the following program.

#include <iostream>

using namespace std;

class X
{
    int i;

    public:
            //X();
            X(int ii);
            void print();
};

//X::X() { }

X::X(int ii)
{
    i = ii;
}


void X::print()
{
    cout<<"i = "<<i<<endl;
}

int main(void)
{
    X x(10);
  //X x1;
    x.print();
  //x1.print();
}

ANd this program seems to be working fine without the default constructor. Please explain why is this the case?? I am really confused with the concept.....

+17  A: 

Yes. Once you explicitly declare absolutely any constructor for a class, the compiler stops providing the implicit default constructor. If you still need the default constructor, you have to explicitly declare and define it yourself.

P.S. It is possible to write a copy constructor (or conversion constructor, or any other constructor) that is also default constructor. If your new constructor falls into that category, there's no need to provide an additional default constructor anymore :)

For example:

// Just a sketch of one possible technique    
struct S {
  S(const S&);
  S(int) {}
};

S dummy(0);

S::S(const S& = dummy) {
}

In the above example the copy constructor is at the same time the default constructor.

AndreyT
"It is possible to write a copy constructor that is also default constructor." How?
dalle
By adding a default argument to a copy construtor, for example. See the example I added to my response.
AndreyT
Can you please clear my edited question? The code works fine without defining the default constructor..
Light_handle
I added a comment there. When the code does not use the default constructor - you don't need to provide one.
AndreyT
themis
Right. But he could always put the copy constructor into the header and put "inline" before it :)
Johannes Schaub - litb
Alternatively, "extern struct S dummy;"-ing it before S and putting the default argument into declaration of the copy constructor would work too.
Johannes Schaub - litb
You can also get away with *only* the copy constructor, providing at the same time the default constructor: `struct X { static X x; X(X const X X::x;` :)
Johannes Schaub - litb
@litb: That's quite extreme, since `x` itself also has to be default-constructed. So, basically, it will receive a reference to itself when it own constructor gets called. I was a bit scared of this Moebius-like situation, so I decided to chicken out and provide a safe alternative constructor for the dummy :)
AndreyT
+2  A: 

You don't have to define both. However, once you define any constructors for a class, all the default ones become unavailable. So - if you want to both copy-construct and to construct without copying, you need to define an non-default (ie explicit) default (ie no parameters) constructor too.

If you define a copy constructor, you should normally override the assignment operator too.

Steve314
You're confusing the issue by overloading the word "default". Not only that but your overloaded meaning of default was explained with the word "explicit" which is another keyword reserved for use with constructors! You can use synthesised instead (with a z if you prefer). :)
Troubadour
The overloading of the word "default" was deliberate - it's just sad that you have no sense of wordplay. As for the word "explicit" - the existence of specialised meanings within the C++ language does not invalidate the pre-existing meanings within the English language. And as for "synthesised" - I thought the goal was to be understood?
Steve314
+1  A: 

As AndreyT said, if you explicitly declare any constructor, including a copy constructor, the compiler will not implicitly declare or define a default constructor.

This is not always a problem.

If you do not want your class to be default-constructible, then it's perfectly fine not to declare a default constructor. But if you want it to be default-constructible (for instance, if you want to uncomment the X x1; line in your example), then you must declare and define a default constructor.

Also note that a default constructor is any constructor that can be called with no arguments, not just one with no arguments. X::X(int = 5) is a perfectly fine default constructor.

coppro