Я следующий простой код с классом, включая обычный конструктор и конструктор копированияC++ амперсанд принимающий объект из функции
class largeObj
{
public:
largeObj()
{
printf("\nNormal constructor\n");
}
largeObj(const largeObj& mv)
{
printf("\nCopy constructor\n");
}
~largeObj()
{
printf("\nDestroying..\n");
}
void tryme()
{
printf("\nHi :)\n");
}
};
largeObj iReturnLargeObjects()
{
largeObj md;
return md;
}
int main()
{
largeObj mdd = iReturnLargeObjects();
mdd.tryme();
return 0;
}
Выход
Обычный конструктор
Copy конструктор
Уничтожение ..
hi :)
и я понял почему.
Но если я заменяю следующую строку
largeObj mdd = iReturnLargeObjects();
с
largeObj& mdd = iReturnLargeObjects();
Выход одно и то же, почему?
Я имею в виду: не должна ли быть другая копия в первом случае (без &)? В чем разница между этими двумя строками и почему они ведут себя одинаково?
Второй не должен компилироваться. Это связывает временную ссылку на неконстантную. – jrok
Я немного отлаживал, и я узнал, что обычный конструктор вызывается объектом md в iReturnLargeObjects(), тогда конструктор копирования вызывается при возврате md; и затем деструктор вызывается на md-объекте непосредственно перед возвратом из iReturnLargeObjects(). Так что, предположительно, в памяти создается еще одна большая Obj. Возникает вопрос: почему объект largeObj mdd = не создает другую переменную копирования? Это из-за RVO? И поэтому все здесь согласны с тем, что второй объект largeObj & mdd = полностью незаконен и скомпилирован из-за чего-то странного – paulAl
@ jrok, он все равно должен компилироваться. Если вы, например, создаете ссылку в стеке, эта ссылка не рассматривается как tempory, потому что компилятор не проверяет, откуда он пришел, только то, что оно является действительной ссылкой, поэтому, когда оно возвращается, оно возвращается как ссылка. Это работает ТОЛЬКО, потому что это конструктор копирования. – 8bitwide