2012-02-09 2 views
0

Таким образом, меня всегда учили, что хорошая практика кодирования заключается в использовании методов доступа по сравнению с непосредственным доступом к переменным-членам, однако при написании перегруженных операторов я не могу скомпилировать, если использовать эти методы доступа в определении класса оператора. Так предположим следующий класс:Можете ли вы использовать методы доступа у перегруженных операторов?

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; 
    }; 

В определении оператора следующее кажется совершенно законно, но это противоречит тому, что я учил:

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

Однако следующая компилирует с ошибкой :

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; 
    } 

последний код будет компилироваться, если «Const» ключевое слово удаляется из пункта который я не совсем понимаю, просто потому, что я передаю переменную const, почему это устраняет мою способность использовать методы доступа?

+1

Ваш оператор '' '' '' '' 'должен быть также' const'. Вы не изменяете этот аргумент. – pmr

ответ

4

Ваших геттерные функции не помечаются как константы, так что не могут быть вызваны постоянным объект:

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

без const ключевого слова, компилятор должен предположить, что функция может изменить объект, и, следовательно, не может быть вызываемый постоянным объектом. Это также хорошо отметить, что в некоторых случаях, вы можете одновременно const и не- const версия, с различными типами возврата, такие как:

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

Использование методов получения и установки является (на мой взгляд) более правильно чем прямой доступ к членам правой стороны.

+2

+1. Я думаю, что ключевым моментом является то, что C++ не знает *, если вы не скажете ему, что это просто геттеры, и что их можно безопасно называть объектом 'const'. (Это хорошо, это означает, что вы не можете случайно написать код, который вызывает метод в объекте 'const', если вы * не намереваетесь * для метода быть' const'-safe, а не, скажем, просто временно 'const'-safe, потому что сейчас это просто пустой заглушка.) – ruakh

4

Изменение:

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; } 

Компилятор жалуется, что предпринимается попытка вызвать метод non-const на const объекта.