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

Нет пути. Ссылка на указатель, доступ к которому осуществляется через * или ->, всегда является lvalue. Он встроен в язык, и типы интеллектуальных указателей стандартной библиотеки соответствуют этому базовому языку.

shared_ptr<container<type>>::operator-> в конечном итоге возвращает container<type>*, к которому применяется оператор стрелки. Оператор стрелки эквивалентен выполнению (*ptr).get(). Таким образом, вы всегда будете применять get() к тому, что язык считает lvalue.

И это значение. Тот факт, что общий указатель является временным, не меняет того факта, что он указывает на занятую память, на lvalue.

12
задан Steve 25 February 2009 в 17:45
поделиться

4 ответа

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

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

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

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

myclass c = 3;

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

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

25
ответ дан 2 December 2019 в 03:33
поделиться

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

5
ответ дан 2 December 2019 в 03:33
поделиться

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

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

Всегда, имейте в виду:

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

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

8
ответ дан 2 December 2019 в 03:33
поделиться

Я записал, что следующие, чтобы попытаться проиллюстрировать понимают то, что продолжается:

#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

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

4
ответ дан 2 December 2019 в 03:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: