可以在重载运算符中使用访问器方法吗

Can you use accessor methods in overloaded operators?

本文关键字:访问 方法 重载 运算符      更新时间:2023-10-16

所以我一直被教导,良好的编码实践是使用访问器方法,而不是直接访问成员变量,但是在编写重载运算符时,如果在运算符类定义中使用这些访问器方法则无法编译。因此,假设以下类别:

    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"参数传递会丢弃限定符[-fpermission]

Point.cpp:8:36:错误:将"const Point{aka const Point}"作为"ushort Point::GetY()"的"this"参数传递会丢弃限定符[-fpermission]

    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变量,为什么这会消除我使用访问器方法的能力?

您的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(在我看来)比直接访问右手边的成员更正确。

更改:

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

编译器抱怨有人试图在const对象上调用non-const方法。