Подтвердить что ты не робот

Синтаксис конструктора С++

Простой вопрос: эквивалентны следующие утверждения? или второй делает более скрытые вещи за кулисами (если да, что?)

myClass x(3);
myClass x = myClass(3);

Спасибо!

4b9b3361

Ответ 1

Они не полностью идентичны. Первая называется "прямой инициализацией", а вторая называется "инициализацией копирования".

Теперь Стандарт составляет два правила. Первый - для прямой инициализации и для инициализации копирования, где инициализатор относится к типу инициализированного объекта. Второе правило - для инициализации копии в других случаях.

Итак, с этой точки зрения оба называются одним - первым - правилом. В случае, если у вас есть инициализация копирования с тем же типом, компилятору разрешено копировать копию, поэтому он может создать временное создание, которое вы создаете непосредственно в инициализированном объекте. Таким образом, вы можете отлично справиться с тем же кодом. Но конструктор копирования, даже если копия завершена (оптимизирована), все равно должна быть доступна. I. Если у вас есть частный конструктор копирования, этот код недействителен, если код, в котором он отображается, не имеет к нему доступа.

Вторая называется copy-initialization, потому что если тип инициализатора имеет другой тип, создается временный объект, пытающийся неявно преобразовать правую сторону в левую сторону:

myclass c = 3;

Компилятор создает временный объект типа myclass, тогда, когда есть конструктор, который принимает int. Затем он инициализирует объект с помощью этого временного. Также в этом случае временное создание может быть создано непосредственно в инициализированном объекте. Вы можете выполнить следующие действия, распечатав сообщения в конструкторах/деструкторах вашего класса и используя опцию -fno-elide-constructors для GCC. Тогда он не пытается выдавать копии.

В боковом примечании этот код выше не имеет ничего общего с оператором присваивания. В обоих случаях происходит инициализация.

Ответ 2

Второй может или не может потребовать дополнительную конструкцию объекта myclass, если ваш компилятор не выполнил копию. Тем не менее, большинство конструкторов включили по умолчанию, даже без какого-либо переключателя оптимизации.

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

Всегда помните:

: уже существующий объект получает новое значение

инициализация: новый объект получает значение в момент его рождения.

Ответ 3

Во втором, сначала создается временный объект, а затем копируется в объект x, используя конструктор myClass copy. Следовательно, оба они не совпадают.

Ответ 4

Я написал следующее, чтобы попытаться <нарисовать > проиллюстрировать понять, что происходит:

#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

Также обратите внимание, что оператор присваивания никогда не вызывается.