Во время работы я натолкнулся на один странный / запутанный фрагмент кода, который, по моему мнению, связан с анонимный объект Концепция жизненного цикла. Ниже приведен пример кода:
#include<iostream>
#include<string>
class A {
private:
int i;
std::string s;
public:
A(int ii, std::string ss = "Hello") { i = ii; s = ss; }
void Display() { std::cout<<i<<"\n"; }
~A() { std::cout<<"A::~A()"<<"\n";}
};
void function()
{
A a = 1;
//A a = A(1);
a.Display();
}
int main()
{
function();
return 0;
}
Выход 1 (если A a = 1) в VS2010
1
A::~A()
Выход 2 (если A a = A (1)) в VS2010
A::~A()
1
A::~A()
output2 совершенно понятно, как деструктор вызывается дважды (в том числе для анонимного) объекта.
тем не мение output1 смущает меня и не в состоянии понять почему деструктор вызывается один раз (не для анонимного) объекта.
A a = 1;
Выше строки вызовет конструктор копирования (A(const A& rhs)
) класса A
и для которого компилятор должен создать анонимный объект, используя параметр 1
, В этом случае деструктор должен вызываться дважды.
Может ли кто-нибудь объяснить мне об этом поведении? Может быть, я упускаю что-то очевидное.
A a = A(1);
эквивалентно A a = 1;
, Однако в обоих случаях копия elision может произойти: A(1)
на самом деле построен непосредственно в a
вместо того, чтобы быть построенным отдельно и затем скопированным или перемещенным.
Компилятор должен решить, следует ли выполнять копирование в любом из разрешенных сценариев (как описано в приведенной выше ссылке).
Ваш компилятор исключает копию для A a = 1
, но не для A a = A(1);
GCC может обходить молчанием копия в обоих случаях, это может быть проверено с -fno-elide-constructors
,