О конструкции копии

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)» и это приведет к ошибке, почему?

0

Решение

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

std::string a, b;
a(b);  // <--- this line?

Нет, конечно нет. Для того, чтобы это скомпилировать, std::string понадобится что-то вроде operator() перегрузка, которая принимает другую строку. Это не имеет этого.

Код в списке инициализации отличается. Выражения в списке инициализации не интерпретируются как обычные операторы, подобные тем, которые находятся внутри тела функции. Они интерпретируются как инициализация (например, вызовы конструктора). Итак, в списке инициализации это:

: price(orig.price)

Это эквивалентно утверждению, как это:

std::string price(orig.price);

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

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

price = orig.price;

Но это отличается от инициализации. Он не будет работать для некоторых типов (таких как const-члены, ссылочные элементы или элементы без конструкторов по умолчанию). И это может быть менее эффективно для некоторых типов, так как вы сначала создаете (с помощью конструктора по умолчанию), а затем присваиваете. Но для многих типов это не имеет большого значения, потому что конструкция по умолчанию практически ничего не стоит.

4

Другие решения

Это неверно, потому что цена уже построена. Вы не можете вызвать его конструктор копирования, если он уже создан.

Вы должны сделать что-то вроде price = orig.price;

1

Изучите ошибку компиляции, и вы поймете, почему. В списке инициализатора члена price(orig.price) является прямая инициализация переменной-члена price со значением orig.price, В теле конструктора копирования price(orig.price) это вызов перегруженного operator() в std::string который принимает std::string, Поскольку такой перегрузки нет, вы получаете ошибку компиляции.

1
По вопросам рекламы [email protected]