簡體   English   中英

為什么必須在運算符重載中提供關鍵字const

[英]why must you provide the keyword const in operator overloads

只是好奇為什么一個param必須是一個const操作重載

CVector& CVector::operator= (const CVector& param)
{
  x=param.x;
  y=param.y;
  return *this;
}

難道你不能輕易做到這樣的事嗎?

CVector& CVector::operator= (CVector& param) //no const
{
  x=param.x;
  y=param.y;
  return *this;
}

當某些東西變成一個const時,它對於應用程序生命的其余部分是不可改變的? 這在操作重載方面有何不同?

你不需要const:

@ numerical25:好奇為什么一個param必須是一個const操作重載

這不是必需的,但這是一個很好的設計決定。

請參閱C ++標准第12.8-9節:

用戶聲明的復制賦值運算符X :: operator =是類X的非靜態非模板成員函數,其中只有一個參數類型為X,X&,const X&,volatile X&或const volatile X&


我認為這是一個好主意:

使用const參數對我來說似乎是一個邏輯設計決策,因為您希望確保不會更改其他值。

它告訴其他人使用你的類,當你說出類似的東西時,你不會改變other值: myObject = other; 並強制執行此操作,以免意外更改other

此外,如果您允許對對象的非const引用作為參數,那么您將限制可以使用您的函數的對象數量。 如果它是const,它可以用於const和非const的參數。 如果您的參數是非const,則它只能由非const的參數使用。


const僅適用於當前引用,而不是對象:

@ numerical25:當某些東西變成一個const時,它對於應用程序生命的其余部分是不可改變的? 這在操作重載方面有何不同?

const引用只是一個const引用。 它不會改變您傳入的實際對象的常量。


非const運算符重載的示例:

以下是運算符重載的示例,其中參數不是const。
我不建議做這件事:

class B
{
public: 
 const B& operator=(B& other)
 {
  other.x = 3;
  x = other.x;
  return *this;
 }

 int x;
};


void main(int argc, char** argv[])
{
 B a;
 a.x = 33;
 B b;
 b.x = 44;
 a = b;//both a and b will be changed
 return 0;
}

const參數在使用它的整個函數中都是const,它不會在它之外改變它的常量。

在這種情況下,您需要聲明一個const參數,以便賦值運算符接受非const變量和const變量; 特別是后一種情況,包括表達式的結果,這是一個臨時的const變量,你通常希望在賦值中支持它。

如果你用過

CVector& CVector::operator= (CVector& param) // no const

然后做了這個:

const CVector& my_vector = GetMyVector();
some_other_vector = my_vector; // call assignment operator - error!

你會得到一個錯誤,因為my_vector是一個const CVector&而且無法轉換為CVector& (非const引用)。 它只是在operator= function中的本地引用,它是const,而不是整個對象本身。

你可以使用非常數變種,但這有兩個反響,一個是功能性的,另一個是關於你作為函數的作者告訴用戶的內容。

1)調用帶有非const引用的函數的人將無法使用const變量調用它

2)當你有一個非const引用的函數參數時,你發出信號,“我保留了改變它的權利”。 通常,當您的函數的用戶寫a = b;時,他不希望b更改。

請注意,您可以使用第三個選項,即按值傳遞:

CVector& CVector::operator= (CVector param) //no reference

這沒有我上面提到的任何問題。 但是,效率非常低。 由於這三個因素,通過引用到const是優選的,特別是在像復制可能很昂貴的向量的情況下。

出於同樣的原因,你可以在任何地方使用const:確保將來對方法的更改不會無意中修改傳入的參數,以幫助記錄接口通知調用者傳遞param是安全的,而不會有更改的風險,並且允許調用者傳入在調用代碼中聲明為const的引用。

另一個原因是允許轉換。 例如:

string s = "foo";
s = "bar";

這里,實現可能選擇僅提供賦值運算符,該賦值運算符將對字符串的const引用作為參數,並依賴編譯器使用構造函數從char *“bar”創建臨時字符串。 如果op ='s參數不是const,這將無效,因為您無法將臨時綁定到非const引用。

const限定符使傳遞的參數(在您的示例中為'const CVector&param')為只讀。 const限定符確保在operator =()方法中不更改參數(param)。

如果沒有const限定符,可以使用以下內容:

CVector& CVector::operator= (CVector& param)
{
  x=param.x;
  y=param.y;

  param.x = 10; // some random value
  param.y = 100;

  return *this;
}

在將值賦給左側操作數之后,上述方法改變右側操作數'param'。 const限定符可幫助您不違反賦值操作的語義。

暫無
暫無

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

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