Jonathan H
Jonathan H

Reputation: 7943

About default and copy constructors

Consider the following code:

#include <iostream>

struct A
{
    A() {} // Can't be commented
    A( const A& other ) =delete;
    int i;
};

struct B : public A
{
    B( int j ) { this->i = j; }
    B( const B& other ) { this->i = other.i; }
};

int main()
{
    B b(42);
    std::cout << b.i << std::endl;
}

Why can't I compile this code if I comment the empty constructor of A? I thought A always had a default constructor, what changes when I disable its copy constructor?

Upvotes: 0

Views: 67

Answers (3)

juanchopanza
juanchopanza

Reputation: 227370

Because this constructor:

B( int j ) { this->i = j; }

is default-initializing B's A sub-object. It is doing the equivalent of this:

B( int j ) : A() { this->i = j; }

Since A has a user-declared non-default constructor (even if it is declared as deleted), the compiler does not synthesize a default constructor for you. So you need to provide it yourself.

Upvotes: 5

Davidbrcz
Davidbrcz

Reputation: 2397

As soon as you declare a constructor in a class (and a deleted one is declared, he is just ... deleted), the compiler will no longer generate any default constructor for you.

So if you comment out the default constructor, you don't have any constructor left for the class A that can be use by B's constructors (because B's constructor is doing a default init of the A part inside B). And it can't call A's default constructor (because there is none !) and the code is ill-formed.

Upvotes: 1

Ivaylo Strandjev
Ivaylo Strandjev

Reputation: 70931

If you have declared at least one non-default constructor, the compiler will not generate a default constructor for you. This actually makes sense if you think a bit. Imagine a class that can be created without some values being passed to the constructor. In this case even you would not be able to create empty constructor, no matter how much you try.

When you comment out the empty constructor of A, the constructors of B will not be able to call it.

When you comment out both constructors, then the compiler considers it OK to generate default implementations for the copy and empty constructors.

Upvotes: 2

Related Questions