Конструкторы по умолчанию и копирование объектов

Мне интересно, почему мне нужно объявить конструктор по умолчанию в этом случае. Во-первых, разве компилятор не сделает это автоматически, если я его опущу? И, тем не менее, я до сих пор не понимаю, зачем это нужно. Кроме того, я получаю сообщение об ошибке, даже если я опускаю 'obj_B = origin.obj_B;'

class B
{
public:
    bool theArray[5] ;

    B(bool x) {theArray[1] = x;};
    //B(){};    
};

class A
{
public:
    B obj_B;

    A() : obj_B(1) {};
    A(A const &origin) {obj_B = origin.obj_B;}; //error:no matching function for call 
                                                      //to B::B()
}; 

int main () 
{
    std::vector <A> someAs;
    for(int q=0;q<10;q++)
        someAs.push_back(A());

    for(int q=0;q<10;q++)
        std::cout << someAs[q].obj_B.theArray[1] << std::endl;
}

4 ответа

Решение

Компилятор создает конструктор по умолчанию, только если вы не указали альтернативный конструктор.

Потому что вы сделали:

B(bool x) {theArray[1] = x;}

Конструктор по умолчанию не будет создан для вас.

Конкретная ошибка, которую вы получаете, заключается в том, что A(const &origin) не указывает конструктор, который будет явно использоваться для obj_B.

Следующий код будет работать:

A(A const &origin) : obj_B(1) {obj_B = origin.obj_B;}

Кстати, вам не нужна конечная точка с запятой в определении функции.

Если вы не определили никакие ctors для класса, компилятор синтезирует конструктор по умолчанию. Если вы определяете другой конструктор (например, тот, который принимает аргумент), то компилятор не синтезирует его для вас, и вы должны определить его самостоятельно.

В случае, если вы заботитесь, C++ 0x добавляет "=default;" объявление, указывающее компилятору предоставить ctor, который он предоставил бы по умолчанию, даже если вы определили другой ctor.

Чтобы определить конструктор копирования для A который не требует конструктора по умолчанию для B, используйте синтаксис инициализатора члена:

class A {
public:
    A(A const& origin) : obj_B(origin.obj_B) {}
    //...
};

Чтобы сделать одно заключительное замечание...

Предполагая, что вы не определили конструктор не по умолчанию, отказ от определения конструктора по умолчанию привел бы к тому, что элементы theArray[] были бы неопределенными. Это плохая привычка, обычно приводящая к ошибкам в будущем.

Другие вопросы по тегам