Сложный вопрос относительно конструктора копирования - PullRequest
0 голосов
/ 10 февраля 2020

Моя путаница лежит в строке Cube c = a;. Я думаю, что он должен вызывать конструктор по умолчанию и конструктор копирования, но на самом деле он вызывает только конструктор копирования. Разве Cube c, как и Cube a, не является новым объектом, который должен вызывать конструктор по умолчанию?

class Cube 
{ 
    public:
        int length_;

        Cube(){
            length_ = 1; 
            cout<< "Default Constr"<< endl; 
        }

        Cube(const Cube & obj){
            length_ = obj.length_;
            cout<< "Copy Constr"<< endl;
        }

}; 

Cube foo(){
    Cube c;
    return c; 
}

int main() { 
    Cube a; //invoke default constructor only
    Cube c = a; //invoke copy constructor only


    return 0; 
} 

Ответы [ 3 ]

3 голосов
/ 10 февраля 2020

Как уже отмечали другие, здесь у вас есть инициализация копирования, поэтому нет способа использовать конструктор по умолчанию.

Существует немного другой случай, когда инициализация копирования может (по крайней мере, теоретически) включать дополнительный шаг. Рассмотрим код, подобный следующему:

class foo { 
public:
    foo(int) {}
};

int main() { 
    foo f = 1;
}

В этом случае (по крайней мере, до C ++ 17) теоретически предполагалось участие двух отдельных конструкторов. Сначала был создан временный объект, инициализированный 1, затем был вызван конструктор копирования для инициализации f из этого временного объекта.

В этом случае большинство компиляторов будут генерировать код, который непосредственно инициализирует f из q, так что это эквивалентно foo f{1};. Тем не менее, компилятор должен учитывать тот факт, что требуется копия, поэтому, если вы удалите конструктор копирования, компиляция завершится неудачно:

class foo { 
    foo(foo const &)= delete;
public:
    foo(int) {}
};

int main() { 
    foo f = 1;
}

Результат (с g cc):

trash9.cpp: In function 'int main()':
trash9.cpp:8:17: error: use of deleted function 'foo::foo(const foo&)'
         foo f = 1;
                 ^
trash9.cpp:2:9: note: declared here
         foo(foo const &) = delete;
         ^~~
trash9.cpp:4:9: note:   after user-defined conversion: 'foo::foo(int)'
         foo(int) {}
         ^~~

Но изменения в правилах, начиная с C ++ 17, означают, что теперь даже это разрешено (поэтому, если я добавлю -std=c++17 к приведенной выше компиляции, это будет успешно).

2 голосов
/ 10 февраля 2020

Когда вы пишете:

Cube c = a;

На самом деле это не назначение, а копия-инициализация .

В вашем случае это было бы так же, как если бы вы написали:

Cube c(a);

Вызывается только конструктор копирования.

Помните, что объект создается только один раз, поэтому только один конструктор.

0 голосов
/ 10 февраля 2020

Вызывается конструктор по умолчанию. Он используется для инициализации объекта. Затем конструктор копирования используется, чтобы установить состояние нового объекта, совпадающее с исходным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...