Załóżmy, że mamy tę klasę:C++ 11 konstruktor ruch nie nazywa, konstruktor domyślny preferowane
class X {
public:
explicit X (char* c) { cout<<"ctor"<<endl; init(c); };
X (X& lv) { cout<<"copy"<<endl; init(lv.c_); };
X (X&& rv) { cout<<"move"<<endl; c_ = rv.c_; rv.c_ = nullptr; };
const char* c() { return c_; };
private:
void init(char *c) { c_ = new char[strlen(c)+1]; strcpy(c_, c); };
char* c_;
};
i ten przykład użycia:
X x("test");
cout << x.c() << endl;
X y(x);
cout << y.c() << endl;
X z(X("test"));
cout << z.c() << endl;
wyjście jest:
ctor
test
copy
test
ctor <-- why not move?
test
Używam VS2010 z ustawieniami domyślnymi. Spodziewałbym się, że ostatni obiekt (z
) zostanie skonstruowany w ruchu, ale tak nie jest! Jeśli używam X z(move(X("test")));
, ostatnie linie wyjścia to ctor move test
, jak można się spodziewać. Czy jest to przypadek (N) RVO?
Q: Czy należy nakazać przeniesienie ctor zgodnie z normą? Jeśli tak, dlaczego tak się nie nazywa?
To kopia elizja. Jeśli elizacja kopiowania nie powiodła się, nastąpiłby ruch. Dlaczego tytuł twojego postu mówi "preferowany konstruktor domyślny"? Nie jest wywoływany żaden domyślny konstruktor, a zamiast konstruktora ruchu nie jest preferowane żadne działanie. Jest całkowicie eliminowany. –
Ten kod nie powinien się kompilować, ponieważ C++ 11; literał łańcuchowy nie może być niejawnie przekonwertowany na nieciągły "char *". –