首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

C++ 運算子多載 基礎與回傳值語義:友元 vs 成員、左值/右值回傳

     編輯:VC 教學

為何需要運算子多載?

自訂類型(如 Complex, Matrix, String)若能直接使用 +, -, ==, << 等運算子,代碼可讀性大幅提升,邏輯更接近數學/領域表達。

多載形式:友元函式 vs 成員函式

基本範例:友元雙目 +、單目前綴 ++


class Test {
    int a;
public:
    Test(int v=0): a(v) {}
    friend Test operator+(const Test&, const Test&);  // 雙目 +
    friend Test& operator++(Test&);                   // 前綴 ++
    int get() const { return a; }
};

Test operator+(const Test& lhs, const Test& rhs) {
    return Test(lhs.a + rhs.a);  // 回傳值(新物件)
}

Test& operator++(Test& obj) {   // 前綴 ++
    ++obj.a;
    return obj;                 // 回傳左值引用
}

回傳值語義鐵律

維度友元函式成員函式
語法friend Type operator@(Type&, Type&);Type operator@(const Type&) const;
參數個數雙目運算子 2 參、單目 1 參隱含 this,雙目 1 參、單目 0 參
對稱性支援隱式轉換雙邊(obj + 1、1 + obj)左運算元**必須**為類物件(1 + obj 需友元/非成員)
存取私有成員需 friend 聲明直接存取
推薦場景雙目運算子、需對稱隱式轉換、輸出運算子 <<單目運算子、賦值 =、下標 []、呼叫 ()、成員存取 ->

不可多載運算子

. (成員存取)、.* (成員指標存取)、:: (作用域解析)、?: (三元條件)、sizeof、typeid、alignof、new/delete (可多載但特殊)、->* (C++11 起可多載)。

優先級與結合性不變

多載**不改變**運算子優先級與結合性。a + b * c 仍先算 * 再 +,無論 operator+/operator* 如何定義。

最佳實踐

  1. 語義一致:+ 要交換律、結合律,== 要等價關係(自反、對稱、傳遞)。
  2. 成對實作:== 配 !=,< 配 > <= >=,+ 配 +=。
  3. 避免驚奇:operator&&/|| 失去短路求值,**極不建議多載**。
  4. 輸出運算子:必須為友元/非成員,第一參數 ostream&,返回 ostream&。
  5. 轉型運算子:explicit operator bool() (C++11) 防止隱式轉 int 參與算術。

總結

運算子多載威力巨大,核心在於**回傳值語義正確**(值 vs 引用)、**形式選擇得當**(友元 vs 成員)、**語義符合直覺**。遵循標準庫慣例(std::string, std::vector, std::complex),你的類型就能像內建型別一樣自然運算。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
運算子類別回傳類型理由範例
算術/邏輯/位元 (雙目) + - * / % & | ^ == != < > <= >= && ||值 (Type)產生新物件,不修改運算元;回傳引用會導致懸空Complex operator+(const Complex&, const Complex&)
複合賦值 += -= *= /= %= &= |= ^= <<= >>=左值引用 (Type&)修改左運算元並返回自身,支援鏈式 a += b += cComplex& operator+=(const Complex&)
前綴遞增/遞減 ++ --左值引用 (Type&)修改自身並返回自身,支援 ++(++a)Test& operator++()
後綴遞增/遞減 ++ --值 (Type)返回修改前的副本,不可作左值Test operator++(int)
賦值 =左值引用 (Type&)支援鏈式賦值 a = b = cTest& operator=(const Test&)
下標 []左值引用 (T&) / const T&支援 arr[i] = val 左值賦值int& operator[](size_t)
解引用 *, 成員存取 ->引用/指標模擬指標語義T& operator*(), T* operator->()
輸出 <<std::ostream&支援鏈式 cout << a << bfriend ostream& operator<<(ostream&, const Test&)