Dla doświadczonych programistów to pewnie banalne, ale jakoś nie mogę tego rozgryźć.
Stworzyłem sobie taką testową klasę:
class Test
{
public:
int Value;
Test() : Value(0)
{
std::cout << "Empty constructor" << std::endl;
}
Test(int V) : Value(V)
{
std::cout << "Normal constructor" << std::endl;
}
Test(const Test& Copy) : Value(Copy.Value)
{
std::cout << "Copy constructor" << std::endl;
}
Test& operator=(const Test& Source)
{
std::cout << "Copy assignment operator" << std::endl;
this->Value = Source.Value;
return *this;
}
};
Testuję w poniższy sposób:
int main()
{
Test T1;
T1 = {};
T1 = { 67 };
}
I dostaję taki output:
Empty constructor
Empty constructor
Copy asignment operator
Normal constructor
Copy asignment operator
Wydaję mi się to zrozumiałe:
W pierwszej linii zostaje wywołany pusty konstruktor dla T1.
W drugiej linii zostaje wywołany pusty konstruktor dla initializer_list w {}, a potem to co utworzono, zostaje przypisane do T1 (trzecia linia)
W czwartej linii zostaje wywołany normalny konstruktor dla { 67 }, a potem utworzony obiekt zostaje przypisany do T1 (piąta linia).
Inaczej to jednak wygląda przy takim kodzie:
Test T1 = { 20 };
T1 = {};
Output:
Normal constructor
Empty constructor
Copy asignment operator
Z zastosowaniem wcześniejszej logiki, powinien zostać najpierw wywołany Normal constructor dla { 20 }, a potem Copy constructor dla T1. Czemu tak się nie dzieje?