2010-03-28 3 views
8

je suis classe donnée avec des variables int x et y en privé, et une fonction de surcharge de l'opérateur,question concernant « ce » pointeur dans C++

class Bag{ 
private: 
    int x; 
    int y; 
public: 
    Bag(); 
    ~Bag(); 
    //....... 
    //.....etc 
}; 


Bag operator+ (Bag new) const{ 
    Bag result(*this); //what does this mean? 
    result.x += new.x;   
    result.y += new.y; 
} 

Quel est l'effet d'avoir « résultat Sac (* ce) " Là?.

+5

La fonction 'operator +' manque-t-elle une instruction 'return'? –

+3

Cela ne semble pas être valide C++ - new is keyword – Artyom

+0

Si vous souhaitez créer des opérateurs, je vous suggère de regarder 'Boost.Operators'. Ils ont regroupé des opérateurs similaires (comme '+ =' et '+') et en écrivant un seul du groupe vous accorde les autres gratuitement :) –

Répondre

10

Bag result(*this) crée une copie de l'objet sur lequel la fonction opérateur a été appelée.

Exemple s'il y avait:

sum = op1 + op2; 

alors result sera une copie de op1. Puisque la fonction operator+ fait une somme de ses opérandes et retourne la somme, nous avons besoin d'un moyen d'accéder à l'opérande op1 qui est fait par le pointeur this.

Sinon, nous aurions pu faire:

Bag result; 
result.x = (*this).x + newobj.x; // note you are using new which is a keyword. 
result.y = (*this).y + newobj.y; // can also do this->y instead 
return result; 
2

La fonction operator+ retourne une copie. La déclaration:

Bag result(*this); 

fait une copie de cet objet pour revenir à l'appelant. Selon la signature, il doit retourner une valeur, donc il fait une copie et ensuite ajouter l'objet new.

4

Tout d'abord, dites à l'éditeur de code de ne pas utiliser new comme nom de variable - c'est un mot-clé. Aussi, rappelez-vous au return result;. Et soit passer par const-référence ou directement modifier le sac new.


l'intérieur d'une struct/classe, this est un pointeur sur lui-même. Par conséquent, *this est une référence à toute l'instance de Bag elle-même.

La déclaration Bag result(a_bag_reference) appellera le constructeur de copie de Bag, ce qui en fait une copie de a_bag_reference en result.

Par conséquent,

Bag result(*this); 

fait une copie de lui-même, puis stocker dans result. Cela rend les 2 prochaines déclarations

result.x += new.x; 
result.y += new.y; 

n'affectent pas l'instance elle-même (à savoir this->x et this->y sont maintenues constantes).

5

Votre code ressemblerait à ceci:

class Bag { 
public: 
    Bag(); 
    Bag(Bag const& other); // copy ctor, declared implicitly if you don't declare it 
    ~Bag(); 

    Bag operator+(Bag const& other) const; 

private: 
    int x; 
    int y; 
}; 

Bag Bag::operator+(Bag const& other) const { 
    Bag result (*this); 
    result.x += other.x;   
    result.y += other.y; 
    return result; 
} 

L'implicite « objet courant » pour les fonctions de membre est pointée par une valeur spéciale nommée ce.Puis obtient cet objet (en déréférencant ce), et il est utilisé pour construire (via le constructeur de copie) un autre sac nommé résultat.

Je soupçonne que ce code est tiré d'un devoir à la maison, alors vous pourriez ne pas être en mesure d'utiliser le modèle one true addition operator, mais il est courant et vous devriez être au courant:

struct Bag { 
    //... 
    Bag& operator+=(Bag const& other) { 
    x += other.x; 
    y += other.y; 
    return *this; // return a reference to the "current object" 
    // as almost all operator=, operator+=, etc. should do 
    } 
}; 

Bag operator+(Bag a, Bag const& b) { 
    // notice a is passed by value, so it's a copy 
    a += b; 
    return a; 
} 
+1

C'est une manière dangereuse d'écrire op +() - le premier paramètre sera tranché , et s'il y avait un comportement polymorphique dans la fonction basée dessus, il n'y en aura pas. Il est préférable de créer les deux références const et de créer la copie dans la fonction. –

+0

@Neil: La copie au sein de la fonction se découpe également en tranches; il est préférable d'utiliser ce modèle jusqu'à ce que vous deviez le changer. Voir aussi http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/ qui promeut le même idiome pour l'opérateur =. –

2

Bag result(*this); est la déclaration d'une variable result et en appelant son constructeur de copie .

Vous pouvez imaginer que C++ déclare automatiquement un constructeur de copie par défaut pour toutes les classes. Son travail est tout simplement d'initialiser un objet en utilisant un autre objet:

Bag::Bag(Bag const& src) { 
    x = src.x; 
    y = src.y; 
}

L'expression *this peut sembler un peu dérangeant, mais est juste l'horreur habituelle de C++ lorsque vous traitez avec & paramètres.