2017-01-28 5 views
3

Ниже приведена часть из раздела 13.1.1. из книги «C++ Prime», 5-е издание:Как понять различия между прямой инициализацией и инициализацией копирования

enter image description here

Для проверки вышеуказанного пункта, особенно в заявлении подчеркнуто красным, я написал следующие коды:

#include<iostream> 
using namespace std; 

class TestClass { 
public: 
    TestClass() :a(7) { 
     cout << "Default constructor"; 
    } 
    TestClass(int aa) : a(aa) { 
     cout << "Constructor" << endl; 
    } 
    TestClass(const TestClass & t): a(t.a) { 
     cout << "Copy constructor" << endl; 
    } 
    TestClass & operator=(const TestClass & rhs) { 
     a = rhs.a; 
     return *this; 
    } 
    int a; 
}; 

int main() { 
    TestClass t1(1); 
    TestClass t2 = t1; 
} 

Основываясь на моем понимании описание инициализации копии в книге, код должен сначала создать t2 с использованием инициализатора по умолчанию, а затем использовать функцию operator= для копирования правого операнда t1. Но когда я отлаживаю строку за строкой в ​​Visual Studio 2015, код переходит прямо к конструктору копирования TestClass(const TestClass & t). Это показывает, что прямая инициализация и инициализация копий на самом деле делают то же самое, без разницы. Итак, мое понимание ошибочно или книга неверна? Если я ошибаюсь, то каково правильное понимание разницы между прямой инициализацией и инициализацией копии? Не могли бы вы дать мне пример кода, чтобы показать такую ​​разницу? Большое спасибо.

Редактировать: кто-то говорит, что на мой вопрос может быть дан ответ в this thread. Но эта нить - это только (подробное и удлиненное) повторение текста, который я выдернул. Он не отвечает, почему на практике (например, Visual Studio 2015) это неверно.

+1

http://stackoverflow.com/questions/1051379/is-there-a-difference-in-c-between-copy-initialization-and-direct-initialization – cpplearner

ответ

1

Книга просто говорит «копировать», что не просто означает назначение копии. Обратите внимание на слово «created», copy initialization означает строительство, а не назначение.

Для TestClass t2 = t1;, t2 будет копироваться из t1 через конструктор копирования напрямую, а не по умолчанию, а затем присваивание.

Если T типа класса и резюме-неквалифицированная версия типа other является T или класса, производным от T, не-явных конструкторов T рассматриваются и лучший матч выбираются разрешение перегрузки , Затем конструктор вызывается для инициализации объекта.

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

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

например.

class TestClass { 
public: 
    // the copy constructor is declared explicit now 
    explicit TestClass(const TestClass & t): a(t.a) { 
     cout << "Copy constructor" << endl; 
    } 
    TestClass(int aa) : a(aa) { 
     cout << "Constructor" << endl; 
    } 
    int a; 
}; 

затем

int main() { 
    TestClass t0(1); 
    TestClass t1(t0); // fine; explicit constructor works fine with direct initialization 
    TestClass t2 = t0; // error; explicit constructor won't be considered for copy initialization 
} 
+0

Я думаю, что мой вопрос не имеет ничего общего с явным. Кроме того, я спрашиваю, как понять описание различий двух типов инициализации в книге. Я не вижу связи между вашим ответом и моим вопросом. – user5280911

+0

@ user5280911 Кажется, вы недопонимаете, что слово «копия» в книге означает «назначение», поэтому я объяснил, что означает «инициализация копирования» в 1-й части.Часть о «явной», это потому, что вы говорите, что прямая инициализация и инициализация копий делают то же самое. – songyuanyao

+0

Я сказал, что они делают то же самое, потому что они выполняют один и тот же код. Извините, я не могу понять ваше объяснение относительно «скопировать правый операнд в создаваемый объект». – user5280911