简体   繁体   English

结构属性运算符重载

[英]Struct property operator overload

I'm writing a game in C++ for my Arduino and I've recently found the joys of operator overloading in structs.我正在为我的 Arduino 用 C++ 编写一个游戏,最近我发现了结构中运算符重载的乐趣。 So far so good!到现在为止还挺好! I'm now stuck on the syntax to overload operators on properties.我现在坚持使用在属性上重载运算符的语法。 I want to implement something like this so that if my x or y values increase over the screen width I wrap the value back to 0. Many thanks!我想实现这样的东西,以便如果我的 x 或 y 值在屏幕宽度上增加,我会将值包装回 0。非常感谢!

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

My struct definition is:我的结构定义是:

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

You can't do this exactly as written.你不能完全按照所写的那样做。 The return type of operator should be type .运算符的返回类型应该是type

What you can do is to create a new type, say coordinate , overload operator++ for it, and have your x (and y ) have coordinate type, not uint8_t .可以做的是创建一个新类型,例如coordinate ,为其重载operator++ ,并使您的x (和y )具有coordinate类型,而不是uint8_t

Possible solution (based on code by @MrMase):可能的解决方案(基于@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;

I've made it a template to allow for a simple typedef to define different coordinates;我已经把它作为一个模板来允许一个简单的typedef来定义不同的坐标; you might also have made MAX a private field and subclass it for different coordinates.您也可能将MAX私有字段并将其子类化为不同的坐标。 In fact, it seems that the template solution is more safe, as it will not allow you to mix different coordinates;实际上,模板解决方案似乎更安全,因为它不允许您混合不同的坐标; however, you might want to reconsider this based on your actual usage.但是,您可能希望根据您的实际使用情况重新考虑这一点。

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

When overloading unary operators (operators with only a single operand, like the increase/decrease operators ++ and -- ) as member functions, they don't have an argument since they are performed on this .当重载一元运算符(只有一个操作数的运算符,如增减运算符++-- )作为成员函数时,它们没有参数,因为它们是在this上执行的。 The exceptions being the dummy int arguments for the postfix increase/decrease operators.例外是后缀增加/减少运算符的虚拟int参数。

The returned value differs depending on which operator you overload, but generally for unary operator you return a reference to object, ie *this .返回值因您重载的运算符而异,但通常对于一元运算符,您返回对对象的引用,即*this

Example例子

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
    }

    ...
};

It's all documented in this operator overloading reference , as well as plenty of tutorials all over the Internet.这一切都记录在这个操作符重载参考中,以及互联网上的大量教程。


On an unrelated note, that operator!= can be implemented by using the == operator that you have already implemented:在一个不相关的注释中,可以使用您已经实现的==运算符来实现该operator!=

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

It's always a good idea to use existing operators when creating related operator overloads.在创建相关的运算符重载时,使用现有运算符总是一个好主意。

It seems it's not possible to overload a property of an enum so I'm going to do the next best thing: create a new type called xcordinate and overload the ++operator似乎不可能重载枚举的属性,所以我要做下一件最好的事情:创建一个名为 xcordinate 的新类型并重载 ++operator

Thanks very much to everyone who helped.非常感谢所有帮助过的人。 I'm grateful!我很感激! :) :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM