Nieoczekiwane zachowanie C ++ (gdzie są moje tymczasowe !?)
Był to eksperyment o wartości r, ale zmutował, gdy gcc jęknął do mnie o braku konstruktora ruchu (usunąłem go) i nie powrócił do konstruktora kopii (jak się spodziewałem). Następnie usunąłem -std = c ++ 11 z flag i wypróbowałem to, co widzisz poniżej, ma dużo wyników (początkowo nie), ponieważ próbuję zrozumieć, dlaczego dokładnie to nie działa (wiem, jak debugować, ale znajduję wiadomości na standardowe wyjście, aby być dobrym wskaźnikiem tego, co się dzieje)
Oto mój kod:
#include <iostream>
class Object {
public:
Object() { id=nextId; std::cout << "Creating object: "<<id<<"\n"; nextId++; }
Object(const Object& from) {
id=nextId; std::cout << "Creating object: "<<id<<"\n"; nextId++;
std::cout<<"(Object: "<<id<<" created from Object: "<<from.id<<")\n";
}
Object& operator=(const Object& from) {
std::cout<<"Assigning to "<<id<<" from "<<from.id<<"\n";
return *this;
}
~Object() { std::cout<<"Deconstructing object: "<<id<<"\n";}
private:
static int nextId;
int id;
};
int Object::nextId = 0;
Object test();
int main(int,char**) {
Object a;
std::cout<<"A ought to exist\n";
Object b(test());
std::cout<<"B ought to exist\n";
Object c = test();
std::cout<<"C ought to exist\n";
return 0;
}
Object test() {
std::cout<<"In test\n";
Object tmp;
std::cout<<"Test's tmp ought to exist\n";
return tmp;
}
Wydajność:
Creating object: 0
A ought to exist
In test
Creating object: 1
Test's tmp ought to exist
B ought to exist
In test
Creating object: 2
Test's tmp ought to exist
C ought to exist
Deconstructing object: 2
Deconstructing object: 1
Deconstructing object: 0
Używam dekonstrukcji, ponieważ dekonstrukcja jest już słowem, czasem używam destruktora, nigdy nie jestem całkiem zadowolony ze słowa, faworyzuję destruktora jako rzeczownika.
Oto, czego oczekiwałem:
A to be constructed
tmp in test to be constructed, a temporary to be created from that
tmp, tmp to be destructed(?)
that temporary to be the argument to B's copy constructor
the temporary to be destructed.
C's default constructor to be used
"" with a temporary from `test`
C's assignment operator to be used
the temporary to be destructed
c,b,a to be destructed.
Zostałem nazwany „die-hard C” i próbuję nauczyć się używać C ++ jako więcej niż „C z przestrzeniami nazw”.
Ktoś mógłby powiedzieć: „kompilator optymalizuje go”. Chciałbym, żeby ta osoba nigdy nie odpowiadała na pytanie taką odpowiedzią, optymalizacje nie mogą zmieniać stanu programu, musi to byćjak gdyby wszystko wydarzyło się tak, jak mówi specyfikacja, więc kompilator może mnie podrażnić, umieszczając wiadomość na cout, która zawiera numer, może nie zawracać sobie głowy nawet zwiększeniem liczby i tak dalej, ale wynik programu byłby taki sam, jak gdyby był zrób wszystko, co opisuje kod.
Więc to nie jest optymalizacja, co się dzieje?