Простой вопрос: эквивалентны следующие утверждения? или второй делает более скрытые вещи за кулисами (если да, что?)
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
Также обратите внимание, что оператор присваивания никогда не вызывается.