关于默认和复制构造函数

时间:2014-01-07 09:54:12

标签: c++ inheritance copy-constructor

请考虑以下代码:

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

如果我评论A的空构造函数,为什么我不能编译这段代码?我以为A总是有一个默认的构造函数,当我禁用它的复制构造函数时会发生什么变化?

3 个答案:

答案 0 :(得分:5)

因为这个构造函数:

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

是默认初始化B的{​​{1}}子对象。它正在做相当于:

A

由于B( int j ) : A() { this->i = j; } 具有用户声明的非默认构造函数(即使它被声明为A),编译器也不会为您合成默认构造函数。所以你需要自己提供。

答案 1 :(得分:2)

如果您已声明至少一个非默认构造函数,则编译器不会为您生成默认构造函数。如果你想一点,这实际上是有道理的。想象一下,可以创建一个没有将一些值传递给构造函数的类。在这种情况下,即使您尝试了多少,也无法创建空构造函数。

当你注释掉A的空构造函数时,B的构造函数将无法调用它。

当您注释掉两个构造函数时,编译器认为可以为复制和空构造函数生成默认实现。

答案 2 :(得分:1)

只要在类中声明构造函数(并且声明了已删除的构造函数,他只是...已删除),编译器将不再为您生成任何默认构造函数。

因此,如果您注释掉默认构造函数,那么B的构造函数可以使用的A类没有任何构造函数(因为B的构造函数正在执行A的默认init )部分内部B)。并且它不能调用A的默认构造函数(因为没有!)并且代码格式不正确。