Copy Constructor and default constructor

21,942

Solution 1

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.

Solution 2

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.

Share:
21,942

Related videos on Youtube

Light_handle
Author by

Light_handle

Updated on July 09, 2022

Comments

  • Light_handle
    Light_handle almost 2 years

    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.....

    • GManNickG
      GManNickG over 14 years
      I'm confused. Although the answer below is correct, that's not a copy constructor. Where are you copying i, exactly? You're modifying the right-hand side, which is generally the wrong thing to do. You should be doing A(const A& rhs) : i(rhs.i) {}, that is copy the right-hand side's i into this instance of A's i. Note the parameters is passed by constant, because when you say something like x = 3, 3 shouldn't change. Also, usually numeric types are passed by value, not reference, because references can be slower for small data types.
    • AnT stands with Russia
      AnT stands with Russia over 14 years
      Your latest program does not use the default constructor anywhere at all. For this reason, you don't need to define it. That's all there's to it.
    • GManNickG
      GManNickG over 14 years
      Indeed, by default the compiler will do a per-member copy automatically, so if you're going to do the same might as well let the compiler do it. Of course, this is a learning exercise, therefore it is exempt.
  • dalle
    dalle over 14 years
    "It is possible to write a copy constructor that is also default constructor." How?
  • AnT stands with Russia
    AnT stands with Russia over 14 years
    By adding a default argument to a copy construtor, for example. See the example I added to my response.
  • Light_handle
    Light_handle over 14 years
    Can you please clear my edited question? The code works fine without defining the default constructor..
  • AnT stands with Russia
    AnT stands with Russia over 14 years
    I added a comment there. When the code does not use the default constructor - you don't need to provide one.
  • themis
    themis over 14 years
    Minor nit: if the "struct S" were in a header file and the "S::S(const S&=dummy)" in the implementation, clients using only the header would not have a default constructor available to them.
  • Johannes Schaub - litb
    Johannes Schaub - litb over 14 years
    Right. But he could always put the copy constructor into the header and put "inline" before it :)
  • Johannes Schaub - litb
    Johannes Schaub - litb over 14 years
    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
    Johannes Schaub - litb over 14 years
    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::x; :)
  • AnT stands with Russia
    AnT stands with Russia over 14 years
    @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 :)

Related