C++ 在typedef结构(c+;+;)中重载运算符

C++ 在typedef结构(c+;+;)中重载运算符,c++,struct,typedef,operator-keyword,C++,Struct,Typedef,Operator Keyword,我想创建一个名为pos(从位置)的typedef结构,它存储坐标x和y。我试图为这个结构重载一些运算符,但它没有编译 typedef struct { int x; int y; inline pos operator=(pos a) { x=a.x; y=a.y; return a; } inline pos operator+(pos a) { return {a.x+x,a.y+y}

我想创建一个名为
pos
(从位置)的typedef结构,它存储坐标x和y。我试图为这个结构重载一些运算符,但它没有编译

typedef struct {
    int x;
    int y;

    inline pos operator=(pos a) {
        x=a.x;
        y=a.y;
        return a;
    }

    inline pos operator+(pos a) {
        return {a.x+x,a.y+y};
    }

    inline bool operator==(pos a) {
       if (a.x==x && a.y== y)
          return true;
       else
          return false;
    }
} pos;
我还想知道这两者之间的区别:

inline bool operator==(pos a) {
    if(a.x==x && a.y== y)
       return true;
      else
       return false;
}
这是:

bool operator==(pos a) const {
      if(a.x==x && a.y== y)
         return true;
      else
         return false;
}

而不是
typedef struct{…}posstruct pos{…}。这里的问题是,在定义类型名称之前,您使用的是
pos
类型名称。通过将名称移动到结构定义的顶部,可以在结构定义本身中使用该名称

此外,
typedef结构{…}名称模式是一个C-ISM,在C++中没有太多的地方。
要回答您关于
内联
的问题,在这种情况下没有区别。当一个方法在结构/类定义中定义时,它被隐式地内联声明。当您显式指定
inline
时,编译器实际上会忽略它,因为该方法已声明为inline

inline
如果在多个对象文件中定义了相同的方法,则这些方法不会触发链接器错误;链接器只会忽略其中一个以外的所有方法,假设它们都是相同的实现。这是内联方法行为的唯一保证更改。现在,它们不会影响编译器的决策不确定是否内联函数;它们只是帮助使函数实现在所有转换单元中可用,这使编译器可以选择内联函数,如果它认为这样做是有益的。)

  • 布尔运算符==(位置a)常量{-此方法不会更改对象的元素
  • 布尔运算符==(位置a){-它可以更改对象的元素
  • 试试这个:

    struct Pos{
        int x;
        int y;
    
        inline Pos& operator=(const Pos& other){
            x=other.x;
            y=other.y;
            return *this;
        }
    
        inline Pos operator+(const Pos& other) const {
            Pos res {x+other.x,y+other.y};
            return res;
        }
    
        const inline bool operator==(const Pos& other) const {
            return (x==other.x and y == other.y);
        }
     };  
    

    您的申报单及其成员的明细有点杂乱无章:

    删除
    typedef

    <> > <代码> TyPulf既不要求,也不希望C++中的类/结构声明。您的成员不知道写的代码> POS < /代码>,这是当前编译失败的核心。

    更改此项:

    typedef struct {....} pos;
    
    bool operator==(pos a) const{
        if(a.x==x && a.y== y)return true;
        else return false;
    }
    
    为此:

    struct pos { ... };
    

    移除无关的入口线

    您正在类定义本身中声明和定义成员运算符。只要实现保持在当前位置(类定义),就不需要
    inline
    关键字


    在适当的地方返回对
    *此
    的引用

    这与实现中大量的复制构造有关,如果没有强有力的理由,就不应该这样做。这与以下内容的表达思想有关:

    a = b = c;
    
    这将
    c
    分配给
    b
    ,然后将结果值
    b
    分配给
    a
    。这不等同于以下代码,与您可能认为的相反:

    a = c;
    b = c;
    
    因此,您的赋值运算符应按如下方式实现:

    pos& operator =(const pos& a)
    {
        x = a.x;
        y = a.y;
        return *this;
    }
    
    即使在这里,也不需要这样做。默认的复制分配操作员将免费为您执行上述操作(代码!woot!)

    注意:在某些情况下,为了使用复制/交换习惯用法,应该避免上述情况。尽管在这种特定情况下不需要这样做,但它可能如下所示:

    pos& operator=(pos a) // by-value param invokes class copy-ctor
    {
        this->swap(a);
        return *this;
    }
    
    然后实现交换方法:

    void pos::swap(pos& obj)
    {
        // TODO: swap object guts with obj
    }
    
    您这样做是为了利用类复制器来创建一个副本,然后利用异常安全交换来执行交换。结果是传入的副本会离开(并破坏)您对象的旧内脏,而您的对象将拥有这些内脏,以及其中的优点和缺点


    适当时通过常量引用传递对象

    所有成员的所有输入参数当前都在复制调用时传递的任何内容。虽然这对于这样的代码来说可能微不足道,但对于较大的对象类型来说可能非常昂贵。下面给出了一个示例:

    更改此项:

    typedef struct {....} pos;
    
    bool operator==(pos a) const{
        if(a.x==x && a.y== y)return true;
        else return false;
    }
    
    对此:(也简化了)

    不复制任何内容,从而生成更高效的代码


    最后,在回答您的问题时,声明为
    const
    的成员函数或运算符与声明为非的成员函数或运算符有什么区别

    const
    成员声明调用该成员将不会修改基础对象(不受可变声明约束)。只能对
    const
    对象或
    const
    引用和指针调用
    const
    成员函数。例如,
    运算符+()
    不修改本地对象,因此应声明为
    const
    。您的
    操作符=()
    明确修改本地对象,因此操作符应
    const


    摘要

    struct pos
    {
        int x;
        int y;
    
        // default + parameterized constructor
        pos(int x=0, int y=0) 
            : x(x), y(y)
        {
        }
    
        // assignment operator modifies object, therefore non-const
        pos& operator=(const pos& a)
        {
            x=a.x;
            y=a.y;
            return *this;
        }
    
        // addop. doesn't modify object. therefore const.
        pos operator+(const pos& a) const
        {
            return pos(a.x+x, a.y+y);
        }
    
        // equality comparison. doesn't modify object. therefore const.
        bool operator==(const pos& a) const
        {
            return (x == a.x && y == a.y);
        }
    };
    

    EDITOP想看看赋值运算符链是如何工作的。下面演示了这一点:

    a = b = c;
    
    相当于:

    b = c;
    a = b;
    
    这并不总是等同于:

    a = c;
    b = c;
    
    示例代码

    #include <iostream>
    #include <string>
    using namespace std;
    
    struct obj
    {
        std::string name;
        int value;
    
        obj(const std::string& name, int value)
            : name(name), value(value)
        {
        }
    
        obj& operator =(const obj& o)
        {
            cout << name << " = " << o.name << endl;
            value = (o.value+1); // note: our value is one more than the rhs.
            return *this;
        }    
    };
    
    int main(int argc, char *argv[])
    {
    
        obj a("a", 1), b("b", 2), c("c", 3);
    
        a = b = c;
        cout << "a.value = " << a.value << endl;
        cout << "b.value = " << b.value << endl;
        cout << "c.value = " << c.value << endl;
    
        a = c;
        b = c;
        cout << "a.value = " << a.value << endl;
        cout << "b.value = " << b.value << endl;
        cout << "c.value = " << c.value << endl;
    
        return 0;
    }
    

    您可能会发现这篇有关堆栈溢出的文章。您可能希望
    pos a
    参数,而不管运算符是
    const pos&a
    (即const引用)而不是一份
    pos
    副本。当然,在您修复声明之后。一旦您解决了问题。您还应该在上发帖,以获取对代码其余部分的评论。您可能需要一些改进。
    typedef
    在这里做什么?干脆放弃它。(使用
    struct
    typedef
    的唯一原因是C兼容性,这意味着没有成员函数,没有朋友等等)我不理解这个“const Pos&other”的意思是不制作副本,并且确信您不修改