跳轉到內容

程式語言入門/過載

來自華夏公益教科書,開放的書籍,開放的世界

一些程式語言支援過載。過載有兩種型別:函式名過載和運算子過載。函式名過載是指在同一作用域記憶體在多個具有相同名稱的成員函式。儘管具有相同的名稱,但這些函式必須具有不同的簽名,簽名包括函式名稱及其引數的型別和順序。以下示例說明了函式名過載的使用。

#include <iostream>
int sum(int a, int b) {
  std::cout << "Sum of ints\n";
  return a + b;
}
double sum(double a, double b) {
  std::cout << "Sum of doubles\n";
  return a + b;
}
int main() {
  std::cout << "The sum is " << sum(1, 2) << std::endl;
  std::cout << "The sum is " << sum(1.2, 2.1) << std::endl;
}

在 main 函式的上下文中,需要選擇合適的 sum 函式來呼叫。這種選擇是透過將呼叫中的實際引數型別與某個宣告中的形式引數型別進行匹配來完成的。這種選擇合適的函式的過程稱為過載解析。如果編譯器無法將函式呼叫與函式宣告匹配,則會丟擲錯誤訊息或異常。正如在強制轉換部分將要討論的那樣,可以使用相同數量的實際引數但型別不完全相同的引數定義來呼叫函式。一些語言提供了某種轉換,以試圖找到匹配項。

透過更改函式名稱使其唯一,可以消除函式名過載。之後,需要找到程式中的每個函式呼叫並將其替換為相應的函式名稱。這種策略是某些語言系統實現過載的方式。它建立了獨立的函式定義,並且每個引用根據涉及的型別進行替換。以下程式碼代表了對函式過載 sum 所做的修改。

#include <iostream>
int sum_i(int a, int b) {
  std::cout << "Sum of ints\n";
  return a + b;
}
double sum_d(double a, double b) {
  std::cout << "Sum of doubles\n";
  return a + b;
}
int main() {
  std::cout << "The sum is " << sum_i(1, 2) << std::endl;
  std::cout << "The sum is " << sum_d(1.2, 2.1) << std::endl;
}

許多語言都支援運算子過載。這個概念與同一個運算子根據其引數的不同而具有不同的實現有關。一些語言允許程式設計師改變運算子的含義。透過這樣做,使用者可以在問題域的語言中程式設計,而不是在機器的語言中程式設計。下面的示例說明了使用 + 運算子進行字串連線以及使用 << 運算子列印 MyString 物件。執行此程式的結果是在螢幕上顯示單詞 "UFMG"。

#include <string.h>
#include <ostream>
#include <iostream>

class MyString {
  friend std::ostream & operator<<(std::ostream & os, const MyString & a) {
    os << a.member1;
  }

  public:
    static const int CAP = 100;
    MyString (const char* arg) {
      strncpy(member1, arg, CAP);
    }
    void operator +(MyString val) {
      strcat(member1, val.member1);
    }

  private:
    char member1[CAP];
};

int main () {
  MyString s1("UF");
  MyString s2("MG");
  s1 + s2;
  std::cout << s1 << std::endl;
}

強制轉換

華夏公益教科書