2015-11-18 2 views
3

J'ai remarqué un comportement qui me semblait étrange. Je fournis un exemple très simplifié pour que nous puissions discuter de ce qui se passe ici.assignation à rvalue: pourquoi compile-t-elle?

est le code ici:

#include <cstdlib> 
#include <iostream> 

using namespace std; 

class A 
{ 
    private: 
    double content; 

    public: 
    A():content(0) 
    {} 
    A(double x):content(x) 
    {} 

    A operator+(const A& other) 
    {  
    content += other.content; 
    return *this; 
    } 

void operator=(const A& other) 
    { 
     content = other.content; 
    } 

    void display() 
    { 
     std::cout<< "content: "<<content<<"\n"; 
    } 


}; 

comme vous pouvez le voir A est une enveloppe pour un double, + et = opérateurs ont été surchargés. (Je comprends ce vide est pas un type typique de retour pour = mais je veux attirer l'attention sur quelque chose d'autre) ici est la fonction principale:

int main(int argc, char *argv[]) 
{ 
A a(1); 
A b(2); 
A c; 
a.display(); //content: 1 
b.display(); //content: 2 
c.display(); //content: 0 

cout<<"\n\n"; 
(a+b) = c ; //this is the most important line why is this legal? 

a.display(); //content: 3 
b.display(); //content: 2 
c.display(); //content: 0 

} 

maintenant je suis un peu confus pourquoi (a + b) = c fonctionne sans problème. (à partir de la sortie, je pourrais dire qu'un a été changé avec succès donc il a 3 comme son contenu.)

Je voudrais savoir pourquoi cette instruction est légale, parce que le résultat de (a + b) doit être une valeur rvalue. Je ne renvoie pas de référence à partir de l'opérateur +, Im ne renvoie qu'une valeur.

esprit que vous, ce n'est pas une valeur temporaire dans le corps de l'opérateur +, mais il est une valeur de toute façon (* this)

Je vous serais reconnaissant des éclaircissements sur ce qui se passe.

+2

Les opérateurs surchargés sont simplement des appels de fonction; ils ne bénéficient d'aucune restriction spéciale sur les catégories de valeur de leurs arguments. Comme vous n'avez pas qualifié à l'origine la surcharge de l'opérateur d'affectation, il accepte les instances de n'importe quelle catégorie de valeur. –

+0

pouvez-vous s'il vous plaît élaborer – ForeverStudent

+1

Eh bien, vous ne vous plaignez pas que '(a + b) .display()' fonctionne, non? –

Répondre

7

(a+b) = c est la même que (a+b).operator=(c). Il n'y a pas de règle spéciale pour les références rvalue dans les opérateurs d'affectation, elle suit simplement les règles d'appel de fonction habituelles. Si vous voulez éviter d'appeler avec rvalues, vous pouvez ajouter un qualificatif ref:

void operator= (const A& other) & { 
//       ^
    content = other.content; 
} 

Cela ne permettra à la fonction à appeler sur lvalues.

+0

donc, normalement = comme l'opérateur d'assignation par défaut nécessite une lvalue sur le côté gauche (à l'exception des références rvalue C++ 11), mais quand je surcharge = moi alors cette exigence sort par la fenêtre, non? – ForeverStudent

+0

@IIIIIIIIIIIIIIIIIIIIIIII oui. – TartanLlama