[英]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.