在Typedef结构(C )中超载运算符

Overloading operators in typedef structs (c++)

本文关键字:中超 超载 运算符 Typedef 结构      更新时间:2023-10-16

我想制作一个称为 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

typedef既不需要,也不需要C 中的类/结构声明。您的成员不了解pos撰写的声明,这是您当前汇编失败的核心。

更改此内容:

typedef struct {....} pos;

struct pos { ... };

删除外部嵌入式

您既声明 and 在类定义本身中定义您的会员运营商。只要您的实现保留在其当前位置(类定义)

,就不需要inline关键字。

在适当的情况下返回*this的引用

这与实施中的大量拷贝构建有关,如果没有强有力的理由,就不应这样做。它与以下的表达意识形态有关:

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!)

Note :有时应避免以上内容以 coppy/swap indiom 。尽管这种特定情况不需要,但看起来像这样:

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
}

您这样做是为了利用类Copy-Ctor制作副本,然后利用异常安全交换来执行交换。结果是传入的副本离开(并摧毁)您的对象的旧胆量,而您的对象则假定存在。在此处阅读更多副本/交换成语以及其中的利弊。


在适当的时候通过cont参考传递对象

您所有成员的所有输入参数当前正在签署Invoke中通过的任何内容。尽管对于这样的代码来说可能是微不足道的,但对于较大的对象类型来说,它可能非常昂贵。这里给出的一个例子:

更改此内容:

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

对此:(也简化)

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

没有任何副本,从而产生了更有效的代码。


最后,在回答您的问题时,将成员函数或运算符声明为const,而不是一个?

const成员声明,调用该成员将修改基本对象(不承受的可变声明)。只能针对const对象或const引用和指针调用const成员函数。例如,您的operator +()不会修改您的本地对象,因此应将其声明为const。您的operator =()明确修改了本地对象,因此操作员应不是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);
    }
};

编辑 OP希望查看分配操作员链的工作原理。以下说明了这一点:

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

输出

b = c
a = b
a.value = 5
b.value = 4
c.value = 3
a = c
b = c
a.value = 4
b.value = 4
c.value = 3

而不是typedef struct { ... } pos;您应该做struct pos { ... };。这里的问题是您在定义pos类型名称之前使用。通过将名称移至struct定义的顶部,您可以在struct定义本身中使用该名称。

此外,typedef struct { ... } name;模式是C-主义,在C 中没有太多位置。

要回答有关inline的问题,这种情况没有区别。当在结构/类定义中定义方法时,它是隐式内联声明的。当您明确指定inline时,编译器有效地忽略了它,因为该方法已经被串联声明。

(如果在多个对象文件中定义了相同的方法,则inline方法不会触发链接器错误;假设它们都是相同的实现。链接器将简单地忽略所有方法。使用内联方法的行为。如今,它们不会影响编译器关于是否要在内联函数的决定;它们只是促进使所有翻译单元中可用的函数实现,这使编译器允许编译器 option inline该功能,如果决定这样做将是有益的。)

尝试以下:

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);
    }
 };  
  1. bool operator ==(pos a)const { - 此方法不会更改对象的元素。
  2. bool operator ==(pos a){ - 它可能会更改对象的元素。