2012-02-09 1 views
0

Ainsi, on m'a toujours enseigné qu'une bonne méthode de codage consiste à utiliser des méthodes d'accès plutôt que d'accéder directement aux variables membres. Cependant, lors de l'écriture d'opérateurs surchargés, je ne peux pas compiler. Supposons donc la classe suivante:Pouvez-vous utiliser des méthodes d'accès dans les opérateurs surchargés?

class Point 
    { 
    public: 
     Point() {}; 
     virtual ~Point() {}; 

     // Accessor Methods 
     inline void SetX(ushort nX) { m_nX = nX; } 
     inline void SetY(ushort nY) { m_nY = nY; } 
     inline ushort GetX() { return m_nX; } 
     inline ushort GetY() { return m_nY; } 

     // Overloaded Operators 
     Point operator+(const Point& pnt); 

    private: 
     ushort m_nX, m_nY; 
    }; 

Dans la définition de l'opérateur, ce qui suit semble parfaitement légal, mais il va à l'encontre de ce que j'ai enseigné:

Point Point::operator+(const Point& pnt) 
    { 
     Point myPoint; 
     myPoint.SetX(GetX() + pnt.m_nX); 
     myPoint.SetY(GetY() + pnt.m_nY); 
     return myPoint; 
    } 

Cependant, ce qui suit compile avec l'erreur :

Point.cpp:7:36: error: passing 'const Point {aka const Point}' as 'this' argument of 'ushort Point::GetX()' discards qualifiers [-fpermissive]

Point.cpp:8:36: error: passing 'const Point {aka const Point}' as 'this' argument of 'ushort Point::GetY()' discards qualifiers [-fpermissive]

Point Point::operator+(const Point& pnt) 
    { 
     Point myPoint; 
     myPoint.SetX(GetX() + pnt.GetX()); // Here I am trying to use accessor methods vs. member variables 
     myPoint.SetY(GetY() + pnt.GetY()); 
     return myPoint; 
    } 

le dernier code compilera si le mot clé 'const' est retiré du para liste de compteur, que je ne comprends pas complètement, juste parce que je passe dans une variable const, pourquoi cela élimine-t-il ma capacité à utiliser les méthodes accesseur?

+1

Votre membre 'operator +' devrait également être qualifié '' const''. Vous ne modifiez pas cet argument. – pmr

Répondre

4

Vos fonctions de lecture ne sont pas marquées comme const, ne peut donc pas être appelé un objet constant:

inline ushort GetX() const { return m_nX; } 
        ^^^^^ 

Sans le mot-clé const, le compilateur doit supposer que la fonction peut modifier l'objet, et ne peut donc pas être appelé sur un objet constant. Il est également bon de noter que, dans certains cas, vous voudrez peut-être à la fois un const et une version non const, avec différents types de retour, tels que:

const_iterator vector<T>::begin() const; //const version 
iterator vector<T>::begin(); //mutable version 

utilisant des accesseurs est (à mon avis) plus correct que d'accéder directement aux membres de la main droite.

+2

+1. Je pense que le point clé est que C++ ne sait * pas *, à moins que vous ne le disiez, que ce ne sont que des getters, et qu'il est prudent de les appeler sur un objet 'const'. (C'est une bonne chose, cela signifie que vous ne pouvez pas écrire accidentellement du code qui appelle une méthode sur un objet 'const' à moins que vous n'ayez * l'intention * de la rendre sûre pour la méthode, plutôt que, disons, temporairement 'const'-safe car pour l'instant c'est juste un bout vide.) – ruakh

4

Change:

inline ushort GetX() { return m_nX; } 
inline ushort GetY() { return m_nY; } 

à:

inline ushort GetX() const { return m_nX; } 
inline ushort GetY() const { return m_nY; } 

Le compilateur se plaint qu'une tentative est faite pour appeler une méthode sur un objet non-constconst.

Questions connexes