конструктор или копировать конструктор? - PullRequest
8 голосов
/ 25 августа 2011

В книге Общее программирование и STL (китайское издание) написано:

X x = X() вызовет конструктор копирования.

Это кажется немного странным для меня. И я пишу тестовую программу, как это

#include <iostream>

class Test {

public:

    Test() {
        std::cout << "This is ctor\n";
    }

    Test(const Test&) {
        std::cout << "This is copy-ctor\n";
    }

};

int main(int argc, char** argv)
{

    Test t = Test();
    return 0;
}

Вывод «Это ctor». хорошо, теперь я в замешательстве, что правильно?

Ответы [ 3 ]

9 голосов
/ 25 августа 2011

Номинально да, временный объект создается по умолчанию, а затем вызывается конструктор копирования, чтобы скопировать его в ваш объект t.

Однако на практике копия может быть оптимизирована вне & mdash; даже при наличии побочных эффектов (вывод на консоль):

[n3290: 8.5/16]: [..] В некоторых случаях реализация разрешено исключить копирование, присущее этому прямая инициализация путем непосредственного построения промежуточного результата в объект инициализируется; см. 12.2, 12.8.

И (в сочетании с примером, приведенным в том же пункте):

[n3290: 12.2/2]: [..] Реализация может использовать временный для построения X (2) перед передачей его в f () с использованием копии X конструктор; альтернативно, X(2) может быть построено в пространстве используется для хранения аргумента. [..]

Но конструктор копирования все еще должен существовать, даже если он не может быть вызван.

В любом случае, если вы компилируете с отключенными оптимизациями (или, с GCC, возможно -fno-elide-constructors), вы увидите:

This is ctor
This is copy-ctor
4 голосов
/ 25 августа 2011

Теоретически, X x = X() вызовет конструктор по умолчанию для создания временного объекта и скопирует его в x с помощью конструктора копирования.

На практике компиляторам разрешено пропускать конструктор копирования напрямую и конструкцию по умолчанию x (что, как указывает Дэвид в своем комментарии, все же требует, чтобы конструктор копирования был синтаксически доступен). Большинство компиляторов делают это, по крайней мере, когда включены оптимизации.

2 голосов
/ 25 августа 2011

Это тот случай, когда форма Оптимизация возвращаемого значения (RVO) (также известная как Copy Elision ) может сильно помочь в оптимизации. Ссылка на страницу википедии очень хорошо объясняет, что происходит.

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