【问题标题】:Struct property operator overload结构属性运算符重载
【发布时间】:2015-09-16 08:44:22
【问题描述】:

我正在为我的 Arduino 用 C++ 编写游戏,最近我发现了在结构中重载运算符的乐趣。到现在为止还挺好!我现在坚持重载属性运算符的语法。我想实现这样的东西,如果我的 x 或 y 值增加超过屏幕宽度,我会将值包装回 0。非常感谢!

// My guess :(
x& operator++(x &newx, int){
    if (x == SCREEN_WIDTH - 1)
        return 0;
    else
        return x + 1;
}

我的结构定义是:

struct point_t
{
    uint8_t x;
    uint8_t y;
    x& operator++(x &newx, int){
        if (x == SCREEN_WIDTH - 1)
            return 0;
        else
            return x + 1;
    }
    point_t& operator=(const point_t &p)
    {
        x = p.x;
        y = p.y;
        return *this;
    }
    bool operator==(const point_t &p) const
    {
        return (x == p.x && y == p.y);
    }
    bool operator!=(const point_t &p) const
    {
        return !(x == p.x && y == p.y);
    }
};

【问题讨论】:

  • 你能发布你的调用代码应该是什么样子吗?我不太明白应该如何使用该运算符。
  • 但是x 不是类型?
  • 嗨!非常感谢!我要做的是调用 mypoint.x++ 或 mypoint.y++ ,当 x 或 v 大于某个最大值时,运算符中的代码会自动将值设置为 0 而不是递增
  • 我想重载结构体的x++、x--、y++和y--属性,这样可以保持一个合适的范围。

标签: c++ struct properties


【解决方案1】:

您不能完全按照书面说明进行操作。运算符的返回类型应该是type

可以做的是创建一个新类型,比如coordinate,为它重载operator++,并让你的x(和y)拥有coordinate类型,而不是uint8_t

可能的解决方案(基于@MrMase 的代码):

template<uint8_t MAX>
class coordinate_t
{
    private:
        int8_t _p;
    public:
        coordinate_t(int8_t p = 0): _p(p) {}

        // Postfix ++
        coordinate_t operator++(int)  
        {
            coordinate_t p(_p);
            ++_p;
            if (_p > MAX - 1)
                _p = 0;
            return p;
        }

        // Postfix --
        coordinate_t operator--(int)  
        {
            coordinate_t p(_p);
            --_p;
            if (_p < 0)
                _p = MAX - 1;
            return p;
        }

        int get() const {return _p;}
};

typedef coordinate_t<SCREEN_WIDTH> xcoordinate_t;
typedef coordinate_t<SCREEN_HEIGHT> ycoordinate_t;

我已经把它做成了一个模板,允许一个简单的typedef 定义不同的坐标;您也可能将MAX 设为私有字段并将其子类化为不同的坐标。实际上,模板解决方案似乎更安全,因为它不允许您混合不同的坐标;但是,您可能需要根据实际使用情况重新考虑这一点。

查看完整示例:http://coliru.stacked-crooked.com/a/5a34261310d05a54

【讨论】:

  • 嗨!非常感谢!我要做的是调用 mypoint.x++ 或 mypoint.y++ ,当 x 或 v 大于某个最大值时,运算符中的代码会自动将值设置为 0 而不是递增
  • 嗨,你是说不能重载结构属性吗?在那个运营商mypoint.x++不能做?谢谢。
  • @MrMase,可以,但前提是mypoint.x是不同的类型,而不是uint8_t
  • @MrMase,感谢您的代码示例。请注意,我已经重写了它;新版本对我来说似乎更具可读性和安全性。即使模板实现不适合您,在您的代码中,我也会将 max 设为 private 成员并通过构造函数设置它;还要注意构造函数初始化列表的使用。
【解决方案2】:

当重载一元运算符(只有一个操作数的运算符,如递增/递减运算符++--)作为成员函数时,它们没有参数,因为它们在this 上执行。后缀增加/减少运算符的虚拟 int 参数除外。

返回值取决于您重载的运算符,但通常对于一元运算符,您返回对对象的引用,即*this

例子

struct point_t
{
    int x;

    // Prefix increase operator
    point_t& operator++()
    {
        ++x;
        return *this;
    }

    // Postfix increase operator
    point_t operator++(int)
    {
        point_t old(*this);  // Create new object using copy-constructor
        operator++();  // Call prefix operator++ on `this`
        return old;  // Return old value, before increment
    }

    ...
};

这一切都记录在this operator overloading reference 中,以及互联网上的大量教程。


另外,operator!= 可以通过使用您已经实现的 == 运算符来实现:

bool operator!=(const point_t& p) const
{
    return !(*this == p);
}

在创建相关运算符重载时使用现有运算符总是一个好主意。

【讨论】:

  • 感谢您的帮助!我不想重载 struct 本身的运算符,我想重载 struct.x++ struct.x-- struct.y++ struct.y 这样我就可以在达到最小值时处理更改值或最大值
  • @MrMase 那么这是不可能的。如果您为坐标创建包装类型,您可以 使用它。但是在修改屏幕坐标时通常是在增加坐标之前进行检查,而不是实际增量的一部分(只是因为它通常需要更多的工作,并且具有增加/减少坐标的特殊功能要容易得多)检查)。
  • 关于operator!= 的第二个提示太棒了!感谢那!我学到了很多东西!
  • 在那种情况下我必须放弃这个想法!我确实在其他地方进行了坐标范围检查。非常感谢! :D :D
【解决方案3】:

似乎不可能重载枚举的属性,所以我要做下一件最好的事情:创建一个名为 xcordinate 的新类型并重载 ++operator

非常感谢所有提供帮助的人。我很感激! :)

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-25
  • 1970-01-01
  • 1970-01-01
  • 2021-02-20
  • 1970-01-01
相关资源
最近更新 更多