В какой строке вызывается конструктор копирования?
У меня есть несколько строк кода, и я не понимаю, почему и где вызывается конструктор копирования. Не могли бы вы объяснить это мне?
Выход:
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;
При попытке подумать о том, когда вызывается конструктор копирования, следует помнить несколько вещей:
- Область действия - функции не могут видеть вне себя и связанного с ними пространства имен. Если вы хотите передать переменную в функцию, вам нужно сохранить ее в глобальной среде, повторно скопировать копию с заданной областью и затем обработать ее.
- Когда вы используете передачу по ссылке, вы работаете с глобальной копией, но поскольку в этом случае вы возвращаете значение, на которое указывает указатель, а не указатель, вы должны поместить это возвращаемое значение в стек отдельно, поскольку оно хранится в другом временном регистре. адрес, который выталкивается из стека после того, как вы назначаете его постоянному месту в main. Вот где приходит деструктор.
- Вы сделали временное возвращаемое значение, чтобы передать значение из вашей функции, поэтому оно должно быть удалено, потому что кэш L1, L2 и L3 - все основные объекты.
Я настоятельно рекомендую немного почитать о кодах ассемблера или даже попробовать собрать простые программы в ассемблер и посмотреть, как работают низкоуровневые языки. Ура!