Скопировать конструктор / оператор присваивания путаницы при инициализации объекта

В чем разница между этим:

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)
Другие вопросы по тегам