所以我总是被告知好的编码实践是使用访问器方法而不是直接访问成员变量,但是在编写重载操作符时,如果在运算符类定义中使用这些访问器方法,我就无法编译。假设以下类:
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:错误:将'const Point {aka const Point}'作为'ushort Point :: GetX()'的'this'参数传递,丢弃限定符[-fpermissive]
Point.cpp:8:36:错误:将'const Point {aka const Point}'作为'ushort Point :: GetY()'的'this'参数传递,丢弃限定符[-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变量,为什么这会消除我使用访问器的能力方法
答案 0 :(得分:4)
您的getter函数未标记为const,因此无法在常量对象上调用:
inline ushort GetX() const { return m_nX; }
^^^^^
如果没有const
关键字,编译器必须假定该函数可能会修改对象,因此无法在常量对象上调用。值得注意的是,在某些情况下,您可能需要具有不同返回类型的const
和非const
版本,例如:
const_iterator vector<T>::begin() const; //const version
iterator vector<T>::begin(); //mutable version
使用getter和setter(在我看来)比直接访问右侧成员更正确。
答案 1 :(得分: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
方法。