class Wood {
public:
Wood();
Wood(const Wood&); //copy constructor
~Wood();
private:
string price;
};
Wood::Wood(const Wood& orig) {
price(orig.price); **//error, why?**
}
Wood::Wood(const Wood& orig) : price(orig.price) { //rigth
}
Если я использую конструкцию инициализировать, и это было правильно. Но если при использовании «price (orig.price)» и это приведет к ошибке, почему?
Тело функции конструктора (часть между открывающей и закрывающей скобками) ничем не отличается от тела любой другой функции. Вы ожидаете, что это скомпилировать:
std::string a, b;
a(b); // <--- this line?
Нет, конечно нет. Для того, чтобы это скомпилировать, std::string
понадобится что-то вроде operator()
перегрузка, которая принимает другую строку. Это не имеет этого.
Код в списке инициализации отличается. Выражения в списке инициализации не интерпретируются как обычные операторы, подобные тем, которые находятся внутри тела функции. Они интерпретируются как инициализация (например, вызовы конструктора). Итак, в списке инициализации это:
: price(orig.price)
Это эквивалентно утверждению, как это:
std::string price(orig.price);
За исключением того, что тип price
не нужно указывать, потому что это уже было сделано в определении класса.
Обратите внимание, что вы не можете выполнить инициализацию члена внутри тела конструктора, потому что к тому времени, когда вы туда попадете, все члены уже инициализированы. Вот почему вам нужен список инициализации. Конечно, вы можете сделать присваивание в теле конструктора:
price = orig.price;
Но это отличается от инициализации. Он не будет работать для некоторых типов (таких как const-члены, ссылочные элементы или элементы без конструкторов по умолчанию). И это может быть менее эффективно для некоторых типов, так как вы сначала создаете (с помощью конструктора по умолчанию), а затем присваиваете. Но для многих типов это не имеет большого значения, потому что конструкция по умолчанию практически ничего не стоит.
Это неверно, потому что цена уже построена. Вы не можете вызвать его конструктор копирования, если он уже создан.
Вы должны сделать что-то вроде price = orig.price;
Изучите ошибку компиляции, и вы поймете, почему. В списке инициализатора члена price(orig.price)
является прямая инициализация переменной-члена price
со значением orig.price
, В теле конструктора копирования price(orig.price)
это вызов перегруженного operator()
в std::string
который принимает std::string
, Поскольку такой перегрузки нет, вы получаете ошибку компиляции.