Простой вопрос: эквивалентны следующие утверждения? или второй делает более скрытые вещи за кулисами (если да, что?)
myClass x(3);
myClass x = myClass(3);
Спасибо!
Простой вопрос: эквивалентны следующие утверждения? или второй делает более скрытые вещи за кулисами (если да, что?)
myClass x(3);
myClass x = myClass(3);
Спасибо!
Они не полностью идентичны. Первая называется "прямой инициализацией", а вторая называется "инициализацией копирования".
Теперь Стандарт составляет два правила. Первый - для прямой инициализации и для инициализации копирования, где инициализатор относится к типу инициализированного объекта. Второе правило - для инициализации копии в других случаях.
Итак, с этой точки зрения оба называются одним - первым - правилом. В случае, если у вас есть инициализация копирования с тем же типом, компилятору разрешено копировать копию, поэтому он может создать временное создание, которое вы создаете непосредственно в инициализированном объекте. Таким образом, вы можете отлично справиться с тем же кодом. Но конструктор копирования, даже если копия завершена (оптимизирована), все равно должна быть доступна. I. Если у вас есть частный конструктор копирования, этот код недействителен, если код, в котором он отображается, не имеет к нему доступа.
Вторая называется copy-initialization, потому что если тип инициализатора имеет другой тип, создается временный объект, пытающийся неявно преобразовать правую сторону в левую сторону:
myclass c = 3;
Компилятор создает временный объект типа myclass, тогда, когда есть конструктор, который принимает int. Затем он инициализирует объект с помощью этого временного. Также в этом случае временное создание может быть создано непосредственно в инициализированном объекте. Вы можете выполнить следующие действия, распечатав сообщения в конструкторах/деструкторах вашего класса и используя опцию -fno-elide-constructors для GCC. Тогда он не пытается выдавать копии.
В боковом примечании этот код выше не имеет ничего общего с оператором присваивания. В обоих случаях происходит инициализация.
Второй может или не может потребовать дополнительную конструкцию объекта myclass, если ваш компилятор не выполнил копию. Тем не менее, большинство конструкторов включили по умолчанию, даже без какого-либо переключателя оптимизации.
Примечание инициализация, а конструкция никогда не вызывает оператор присваивания.
Всегда помните:
: уже существующий объект получает новое значение
инициализация: новый объект получает значение в момент его рождения.
Во втором, сначала создается временный объект, а затем копируется в объект x, используя конструктор myClass copy. Следовательно, оба они не совпадают.
Я написал следующее, чтобы попытаться <нарисовать > проиллюстрировать понять, что происходит:
#include <iostream>
using namespace std;
class myClass
{
public:
myClass(int x)
{
this -> x = x;
cout << "int constructor called with value x = " << x << endl;
}
myClass(const myClass& mc)
{
cout << "copy constructor called with value = " << mc.x << endl;
x = mc.x;
}
myClass & operator = (const myClass & that)
{
cout << "assignment called" << endl;
if(this != &that)
{
x = that.x;
}
return *this;
}
private:
int x;
};
int main()
{
myClass x(3);
myClass y = myClass(3);
}
Когда я компилирую и запускаю этот код, я получаю следующий вывод:
$ ./a.out
int constructor called with value x = 3
int constructor called with value x = 3
Это будет показаться, чтобы указать, что между двумя вызовами, сделанными в основной функции, нет разницы, но это было бы неправильно. Как отмечалось в litb, конструктор копирования должен быть доступен для работы этого кода, даже если в этом случае он будет устранен. Чтобы доказать это, просто переместите конструктор копирования в приведенный выше код в частный раздел определения класса. Вы должны увидеть следующую ошибку:
$ g++ myClass.cpp
myClass.cpp: In function ‘int main()’:
myClass.cpp:27: error: ‘myClass::myClass(const myClass&)’ is private
myClass.cpp:37: error: within this context
Также обратите внимание, что оператор присваивания никогда не вызывается.