2015-08-14 32 views
17

Sono nuovo del C++. Il libro che ho letto mi dice che se l'operatore più (+) è stato sovraccaricato per qualche oggetto di classe, ad esempio la classe string, per rendere questo problema più concreto.L'operatore +, differenza tra tipi di classi e tipi built-in?

#include<iostream> 
#include<string> 
using namespace std; 

int main() 
{ 
    string s1("abc"); 
    string s2("def"); 

    string s3("def"); 

    cout<<(s1+s2=s3)<<endl; 

    int x=1; 
    int y=2 
    int z=3; 
    cout<<(x+y=z)<<endl; 

    return 0; 
} 

Come ci si potrebbe aspettare, la prima cout affermazione è corretta, mentre il secondo è sbagliato. Il reclamo del compilatore x+y non è un lvalue modificabile. La mia domanda è: perché l'operatore + restituisce un lvalue modificabile per gli oggetti string ma non per int?

+2

In C++, gli oggetti sono istanze di qualsiasi tipo, inclusi i tipi built-in. E i tipi sono tipi. Quindi "oggetti" contro "tipi built-in" non ha senso. – juanchopanza

+1

@juanchopanza Sarebbe utile fornire la dicitura corretta mentre ci si trova :) – Quentin

+1

@Quentin Suppongo che "la differenza tra tipi predefiniti e tipi definiti dall'utente" sia accurata. – juanchopanza

risposta

20

Non restituisce un lvalue modificabile per la stringa. Restituisce un oggetto temporaneo e s1+s2 e x+y sono entrambi rvalues.

Tuttavia, gli oggetti di tipo classe potrebbero aver sovraccaricato operator=, che fa string. È consentito chiamare le funzioni membro su rvalue.

La differenza tra i due casi è in = (non +)

+1

Si noti che questo è un problema che viene [elaborato] (http://stackoverflow.com/a/21052529/15416). Puoi evitare di chiamare 'operator =' su rvaliues delle tue classi. Il problema è che c'è un codice esistente che si interromperebbe se lo standard C++ venisse modificato per proibire l'assegnazione ai valori di 'std :: string'. – MSalters

+0

@MSalters Sì, [un uomo saggio] (http://stackoverflow.com/questions/28598468/does-it-improve-safety-to-mark-assignment-operators-as-lvalue-only) una volta chiesto lo stesso. . :) –

14

Per std::string, s1 + s2 = s3 è infatti:

(operator+(s1, s2)).operator =(s3) 

s1 + s2 restituisce un rvalue

metodi Stati possono essere applicati a anche temporaneo.
Poiché C++ 11, abbiamo la qualificazione lvalue/rvalue per il metodo,
in modo da può vietare o1 + o2 = o3 per il vostro tipo personalizzato con:

struct Object 
{ 
    Object& operator =(const Object& rhs) & ; // Note the & here 
}; 

così Object::operator = può essere applicato solo alle lvalue.