2016-01-05 9 views
5

Jestem nowy w programowaniu. Przepraszam za mój zły angielski. Próbowałem użyć rvalue jako inicjalizatora dla obiektów początkowych. Tak więc, zgodnie z kodem, wydrukowałby, jaki jest używany konstruktor i operator przypisania. Ale okazało się, że obiekt "co2" i "co3", to nic nie drukuje. oto kod:rvalue jako inicjator do budowy obiektu

#include <iostream> 
using namespace std; 
class X{ 
public: 
    int x; 
    X()= default; 
    X(int num):x{num}{} 
    X(const X& y){ 
     x = y.x; 
     std::cout << "copy constructor" << std::endl; 
     std::cout << x << std::endl; 

    } 
    X& operator=(const X& d){ 
     x = d.x; 
     std::cout << "copy assignment" << std::endl; 
     return *this; 
    } 
    X(X&& y){ 
     x = y.x; 
     std::cout << "move constructor" << std::endl; 
    } 
    X& operator=(X&& b){ 
     x = b.x; 
     std::cout << "move assignment" << std::endl; 
     return *this; 
    } 
}; 

X operator +(const X& a,const X& b){ 
    X tmp{}; 
    tmp.x = a.x +b.x; 
    return tmp; 
} 

int main(int argc, const char * argv[]) { 
    X a{7} , b{11}; 
    X what1; 
    cout << "---------------" << endl; 
    what1 = a+b; 
    cout << "---------------" << endl; 
    X what2{a+b}; 
    cout << "---------------" << endl; 
    X what3 = a+b; 
    cout << "---------------" << endl; 
    std::cout << what1.x << std::endl; 
    std::cout << what2.x << std:: endl; 
    std::cout <<what3.x << std::endl; 
    return 0; 
} 

wyjście jest:

--------------- 
move assignment 
--------------- 
--------------- 
--------------- 
18 
18 
18 
Program ended with exit code: 0 
tylko

"what1" używa zadanie prawidłowo. , więc w jaki sposób mogę użyć wartości r do zainicjowania obiektu? i za pomocą operatora = do parafowania obiektu? dziękuję bardzo.

+3

Być może przydatne: [Copy elizja] (https: // pl. wikipedia.org/wiki/Copy_elision) – AndyG

+0

Wypróbuj 'X what3 = std :: move (what1);' i zobacz, co się stanie. – AndyG

+0

Jak mogę go wyłączyć? Ponieważ chcę zobaczyć, jak nazywa się kopiowanie lub przenoszenie. –

Odpowiedz

4

Twój kod może spowodować użycie operacji przenoszenia, ale Twój kompilator wybrał te ruchy na elide i przydzieli powrót na numer operator+ bezpośrednio na stronie połączenia. Możesz to zobaczyć, jeśli wyłączysz kopiowanie w swoim kompilatorze (-fno-elide-constructors w GCC lub Clang).

Twój ruch konstruktor i operator przypisania będzie z powodzeniem stosowane w sytuacjach, w których kopiowanie elizja nie jest dopuszczalne, takie jak ten:

X what2 { std::move(what1) }; //can't elide copy, move constructor used 
+0

X what3 = a + b; // Chcę wiedzieć, jak to działa. Po prostu się ruszaj? lub utworzyć pusty obiekt "what3", a następnie wprowadzić? Dzięki. –

+1

Z elision kopiowania zwrot 'a + b' zostanie przydzielony bezpośrednio do' what3'. Bez tego jest to pojedyncze wywołanie konstruktora ruchu. Ten formularz jest znany jako * inicjowanie kopii *. – TartanLlama

0

Poniższy kod wyzwala więcej swoich konstruktorów/operatorów, to sprawdzić, aby zobaczyć, które spust w jakich przypadkach

#include <iostream> 
using namespace std; 
class X{ 
public: 
    int x; 
    X() 
    { 
     x = 0; 
     std::cout << "constructor" << std::endl; 
    } 
    X(int num):x{num} 
    { 
     std::cout << "list initilizer" << std::endl; 
    } 
    X(const X& y){ 
     x = y.x; 
     std::cout << "copy constructor" << std::endl; 
    } 
    X& operator=(const X& d){ 
     x = d.x; 
     std::cout << "copy assignment" << std::endl; 
     return *this; 
    } 
    X(X&& y){ 
     x = y.x; 
     std::cout << "move constructor" << std::endl; 
    } 
    X& operator=(X&& b){ 
     x = b.x; 
     std::cout << "move assignment" << std::endl; 
     return *this; 
    } 
}; 

X operator +(const X& a,const X& b){ 
    X tmp{}; 
    tmp.x = a.x +b.x; 
    return tmp; 
} 

int main(int argc, const char * argv[]) { 
    X a{7} , b{11}; 
    cout << "---------------" << endl; 
    X what1; 
    cout << "---------------" << endl; 
    what1 = a+b; 
    cout << "---------------" << endl; 
    X what2(a+b); 
    cout << "---------------" << endl; 
    X what3 = X(a); 
    cout << "---------------" << endl; 
    X what4 = X(); 
    cout << "---------------" << endl; 
    X what5 = std::move(what1); 
    cout << "---------------" << endl; 
    what5 = std::move(what1); 
    cout << "---------------" << endl; 
    what5 = what1; 
    cout << "---------------" << endl; 
    return 0; 
}