@sddvxd

Какова очередность присваивания нового объекта?

Здравствуйте, хочу разобраться вот в чем:

Type a;
Type b = a; //Тут вызывается operator= или конструктор копирования?

В литературе что я читаю это называется присваиванием, но оператор присваивания возвращает ссылку на аргумент:
Type& Type::operator=(const Type&);
А это значит, что манипулируя членами b я буду редактировать память a? Если по такой логике я создал псевдоним

У меня есть еще одна теория: поскольку эту неявное преобразование, вызывается конструктор копирования:
Type b = Type(a);
Вторым шагом вызывается оператор присваивания, беря в аргумент скопированный уже в новом участке памяти новенький объект и возвращает ссылку только что родившемуся объекту:
Type b = (operator=(&(Type(&a))))//Абстракция, не сочтите за ошибку
  • Вопрос задан
  • 76 просмотров
Пригласить эксперта
Ответы на вопрос 2
@polar_winter
#include <iostream>

class A 
{
public: 
    A()
    {
        c = counter++;
    };

    int c;   
 
private:

    static int counter;
};

int A::counter =0;

int main (int argc, char ** argv)
{
    A a1;
    A a2;
    A a3;
    std::cout << a1.c << a2.c << a3.c << std::endl;
    std::cout << (a2 = a1).c <<std::endl;
    std::cout << a1.c << a2.c << a3.c << std::endl;
    
    a2.c = 1;
    std::cout << a1.c << a2.c << a3.c << std::endl;
   
    return 0;
}


012
0
002
012

Вы, вероятно, не так поняли, что значит оператор присваевания возвращает. Второй вывод stdcout
Ответ написан
Комментировать
@Mercury13
Программист на «си с крестами» и не только
А это значит, что манипулируя членами b я буду редактировать память a?

Нет, конечно.

Type& Type::operator=(const Type& x);
Задача операции присваивания — сделать, чтобы объект слева (он же *this) стал копией объекта справа (он же x).

Почему операция присваивания берёт Type& по ссылке? Да потому, что взять по копии — это вызвать конструктор копирования. Вполне можно написать
BigInt& BigInt::operator = (int x);
когда слева «большой» тип, а справа — «маленький», и его конструктор копирования незначителен (а то и равняется накладным расходам на ссылку, как у того же int). Но когда с обеих сторон один и тот же тип — это часто бездумный вызов конструктора копирования (собственные конструктор копирования и операцию = обычно пишут, когда нужна хитрая логика, а не тривиальное копирование).

Почему операция присваивания возвращает Type&? Просто чтобы работали конструкции типа a = b = c. Может и void возвращать, если хочешь.

class C
{
public:
    C() {}
    C (const C&) { std::cout << "Copy ctor" << std::endl; }
    C & operator = (const C&) { std::cout << "Assign" << std::endl; return *this; }
};

int main()
{
    C a;
    C b = a;

Выведет «Copy ctor». То есть ответ на первый вопрос — конструктор копирования.

В литературе что я читаю это называется присваиванием

Не присваивание, а инициализация. Присваиванием было бы…
Type b;
b = a;


Type b = Type(a);

В идеале тут два конструктора копирования и один деструктор, однако компилятору даётся воля уменьшать их количество. Потому только «copy ctor».

Код
int a = 10;
C b = C(a);

также даёт один вызов C(int). А C(const C&) не вызывается ни разу.

UPD. Одно из нововведений Си++11 — чтобы даже без этих негарантированных оптимизаций, когда один объект исчезает, а второй появляется, можно было вместо копирования проводить нечто более простое, не требующее отвода-возврата памяти. Я-то экспериментировал в режиме Си++03, но в Си++11 уже были бы конструктор копирования, конструктор перемещения и деструктор.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы