2016-02-15 11 views
7

Chciałbym wyłączyć konstruktor ruchu w klasie. Zamiast poruszać się, chciałbym oprzeć się na konstruktorze kopii. Kiedy próbuję napisać ten kod:Wyłączanie konstruktora ruchu

class Boo 
{ 
public: 
    Boo(){} 
    Boo(const Boo& boo) {}; 
    Boo(Boo&& boo) = delete; 
}; 

Boo TakeBoo() 
{ 
    Boo b; 
    return b; 
} 

podczas kompilacji otrzymałem błąd:

error C2280: 'Boo::Boo(Boo &&)': attempting to reference a deleted function

Jak mogę wyłączyć konstruktora ruch i siły kopie zamiast?

+6

prostu nie przeciążyć konstruktora ruch i kompilator nie wygeneruje konstruktora ruch dla niego, ponieważ nie jest już konstruktor kopia –

+2

od standardu: „Jeżeli definicja klasy X nie jawnie zadeklarować konstruktor ruchu, jeden będzie domyślnie zadeklarowany jako domyślny wtedy i tylko wtedy, gdy X nie posiada deklarowanego przez użytkownika konstruktora kopiowania [...] Gdy konstruktor ruchu nie jest domyślnie zadeklarowany lub jawnie dostarczony, wyrażenia, które w przeciwnym razie wywołałyby ruch konstruktor może zamiast tego wywołać konstruktora kopii. " – Pixelchemist

+1

Co masz nadzieję osiągnąć przez to? W żaden sposób nie ma to żadnego znaczenia. –

Odpowiedz

17

nie tworzy żadnego konstruktora ruch:

class Boo 
{ 
public: 
    Boo(){} 
    Boo(const Boo& boo) {}; 
}; 

Konstruktor ruch nie jest automatycznie generowany tak długo, jak konstruktor kopia zdefiniowany przez użytkownika jest obecna tak konstruktor kopia jest tzw.

+6

Konstruktor ruchu nie jest generowany automatycznie *, jeśli obecny jest konstruktor kopii *. Tak jest w przypadku OP, ale warto to wskazać, aby czytelnik nie doszedł do wniosku, że niewdrożenie konstruktora ruchu wystarczy, aby uniknąć ruchów. Na przykład klasa o dwóch elementach 'std :: vector' i nieskonfigurowanych konstruktorów kopiowania lub przenoszenia otrzyma automatycznie wygenerowany konstruktor ruchu, który porusza wektory. – user4815162342

4

Oznaczenie funkcji jako =delete powoduje, że funkcja jest dostępna dla rozdzielczości przeciążenia, ale jeśli wybrana, kompilacja się nie powiedzie; ta funkcjonalność nie jest ograniczona do konstruktorów i innych funkcji specjalnych (see here). Wcześniej (około C++ 03) sprawienie, by członek prywatny osiągnął podobny rezultat.

W związku z tym kod jak w próbce, oznacza w praktyce uniemożliwienie zbudowania obiektu klasy z tymczasowej lub wygasającej wartości (rvalues) - konstruktora ruchu.

Aby to poprawić, należy całkowicie usunąć konstruktor ruchu. W przypadku klasy, gdy konstruktor kopiowania jest obecny (zdefiniowany przez użytkownika), ruch ten nie jest generalnie generowany (konstruktor ruchu i operator przypisania ruchu).

class Boo 
{ 
public: 
    Boo(){} 
    Boo(const Boo& boo) {}; 
    //Boo(Boo&& boo) = delete; 
}; 
+2

Dodatkowe informacje: oznaczenie konstruktora ruchu jako usuniętego sam w rzeczywistości udostępnia go dla rozdzielczości przeciążania; jeśli jednak konstruktor ruchu jest niejawnie zdefiniowany jako usunięty (np. dzieje się tak, jeśli zmienna składowa ma zdefiniowany konstruktor ruchu jako usunięty, niejawnie lub jawnie), wówczas * nie * jest dostępny dla rozdzielczości przeciążenia !. (Rozdzielczość przeciążenia jest fajna ...) –

Powiązane problemy