Скопировать конструктор / оператор присваивания путаницы при инициализации объекта
В чем разница между этим:
class_name object_name = something;
а также
class_name object_name(something);
Из того, что я здесь прочитал, оба используют конструктор копирования, но я не понимаю, почему это происходит и как в игру вступают неявные преобразования. Насколько я понял (до того, как прочесть об этом), сначала я использовал оператор присваивания по умолчанию (если он не определен), создав временный объект, а затем вызвал конструктор копирования, но, похоже, это неправильно. Я спрашиваю, потому что я прочитал, что при явном создании конструктора копирования первый параметр потерпит неудачу, даже если что-то имеет тип class_name, поэтому эти два параметра должны быть достаточно разными. Также используется оператор присваивания (с использованием реализации по умолчанию или пользовательской реализации) поверх конструктора копирования в первом варианте или это просто удобная синтаксическая форма вызова конструктора копирования?
2 ответа
Конструктор копирования и оператор присваивания не одно и то же.
Test(const Test &t)
{
std::cout<<"Copy constructor called "<<std::endl;
}
Test& operator = (const Test &t)
{
std::cout<<"Assignment operator called "<<std::endl;
return *this;
}
Test t1, t2;
t2 = t1;
Test t3 = t1;
В этом примере оператор присваивания вызывается для t2 = t1
и конструктор копирования вызывается для t3 = t1
,
Если вы сделаете конструктор копирования явным, вы должны вызвать его следующим образом:
Test t3(t1);
Если конструктор копирования является явным, первая форма может быть получена только с помощью записи:
class_name object_name = class_name(something);
т.е. явно вызывая конструктор копирования.
В конце, тем не менее, если конструктор копирования является явным, просто используйте первую форму, если она однозначна (остерегайтесь самого неприятного анализа), или для дополнительных C++11 точек используйте синтаксис инициализатора фигурных скобок, который никогда не может быть неоднозначным:
class_name object_name{something};
ИЛИ используя идею Херба Саттера "почти всегда авто":
auto object_name = class_name{something};
Чтобы ответить на ваш другой вопрос, здесь не используются операторы присваивания или копирования. Оператор копирования-назначения используется, когда вы назначаете копию ранее инициализированной переменной:
class_name object_name;
object_name = class_name(something); // uses class_name& operator= (class_name& other)