В какой строке вызывается конструктор копирования?

У меня есть несколько строк кода, и я не понимаю, почему и где вызывается конструктор копирования. Не могли бы вы объяснить это мне?

Выход:

CS10

CS99

CC100

Obj10 = Obj100

D100

Obj10 = Obj99

D99

D10

Это мой исходный код:

#include <iostream>

using namespace std;

class my
{
    int m;
public:
    my(int i): m(i)
    {
        cout << "CS" << m << endl;
    }
    my(const my& c): m(c.m+1)
    {
        cout << "CC" << m << endl;
    }
    ~my()
    {
        cout << "D" << m << endl;
    }
    my& operator=(const my &c)
    {
        cout << "Obj" << m << "=Obj" << c.m << endl;
        return *this;
    }
};

my f(my* x)
{
    return *x;
}

int main()
{
    my m1(10);
    my m2(99);

    m1 = f(&m2); // creates a new object
    m1 = m2;     // does not create a new object
}

Почему и где вызывается конструктор копирования, вызывающий вывод CC100 и D100?

2 ответа

Решение

В этой функции

my f(my* x)
{
    return *x;
}

называется в заявлении

m1 = f(&m2); // creates a new object

конструктор копирования вызывается для копирования объекта *x в возвращаемом временном объекте.

На самом деле это выглядит как

my tmp = *x; // the copy constructor is called
m1 = tmp;

При попытке подумать о том, когда вызывается конструктор копирования, следует помнить несколько вещей:

  1. Область действия - функции не могут видеть вне себя и связанного с ними пространства имен. Если вы хотите передать переменную в функцию, вам нужно сохранить ее в глобальной среде, повторно скопировать копию с заданной областью и затем обработать ее.
  2. Когда вы используете передачу по ссылке, вы работаете с глобальной копией, но поскольку в этом случае вы возвращаете значение, на которое указывает указатель, а не указатель, вы должны поместить это возвращаемое значение в стек отдельно, поскольку оно хранится в другом временном регистре. адрес, который выталкивается из стека после того, как вы назначаете его постоянному месту в main. Вот где приходит деструктор.
  3. Вы сделали временное возвращаемое значение, чтобы передать значение из вашей функции, поэтому оно должно быть удалено, потому что кэш L1, L2 и L3 - все основные объекты.

Я настоятельно рекомендую немного почитать о кодах ассемблера или даже попробовать собрать простые программы в ассемблер и посмотреть, как работают низкоуровневые языки. Ура!

Другие вопросы по тегам