簡體   English   中英

在typedef結構中重載運算符(c ++)

[英]Overloading operators in typedef structs (c++)

我想創建一個名為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 -written的聲明,這是您當前編譯失敗的核心。

改變這個:

typedef struct {....} pos;

對此:

struct pos { ... };

刪除無關的內聯

您既可以在類定義中聲明定義成員運算符。 只要您的實現保留在其當前位置(類定義),就不需要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!)

注意 :有時應避免使用上述內容,以支持復制/交換習慣用法 雖然這個特定情況不需要,但它可能如下所示:

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制作副本,然后利用異常安全交換來執行交換。 結果是傳入的副本會離開(並銷毀)對象的舊內容,而您的對象則擁有對象的所有權。 閱讀更多復制/交換習語 ,以及其中的優點和缺點。


適當時通過const引用傳遞對象

您所有成員的所有輸入參數當前都在復制調用時傳遞的內容。 雖然對於像這樣的代碼來說可能是微不足道的,但對於較大的對象類型來說它可能非常昂貴。 這里給出一個例子:

改變這個:

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引用和指針調用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);
    }
};

EDIT 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類型名稱。 通過將名稱移動到結構定義的頂部,您可以在結構定義本身中使用該名稱。

此外, typedef struct { ... } name; pattern是一個C-ism,在C ++中沒有多少位置。

要回答關於inline的問題,這種情況沒有區別。 在struct / class定義中定義方法時,它是內聯隱式聲明的。 當您明確指定inline ,編譯器會有效地忽略它,因為該方法已經內聯聲明。

(如果在多個目標文件中定義了相同的方法, 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){ - 它可能改變對象的元素。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM