該文爲中國大學MOOC上北京郵電大學崔毅東和楊談老師主講的《C++程序設計(面向對象進階)》筆記整理
1. 變量的作用域
- 作用域的分類
-
全局作用域:全局變量
-
局部作用域:局部分類
如果外部代碼塊和內嵌代碼塊有同名變量,那麼會產生同名覆蓋,此時遵循"就近原則"
-
一元作用域解析運算符
當局部變量與全局變量相同時,可使用 :: 訪問全局變量,該運算符被稱爲一元作用域解析運算符
#include<iostream> int i = 10; int main() { int i = 5; for (int i = 0; i < 4; i++) { std::cout << i << std::endl; // 訪問的是 for 循環中的 i std::cout << ::i << std::endl; // 訪問的是全局變量 i,而不是 for 前面的 i } return 0; }
2. 重載函數
重載函數是在同一個名字空間中存在兩個或多個具有相同名字的函數所構成的語法現象
調用重構函數的語句,是編譯器在編譯期確定的
編譯器確定重構函數的依據是函數參數的類型、個數和次序,無法根據函數的返回值判斷
如果編譯器無法判定,就會報告二義性錯誤
#include<iostream>
auto max(int a, int b) {
return a > b ? a : b;
}
auto max(double a, double b) {
return a > b ? a : b;
}
int main() {
std::cout << max(4,2) << std::endl; // 調用第一個 max
std::cout << max(4.5, 2.2) << std::endl; // 調用第二個 max
return 0;
}
3. 帶有默認值的函數
函數的參數可以指定默認值
指定默認值時,要保證帶默認值的參數位於函數列表的右側
int max(int a,int b = 1,int c); // error
int max(int a,int b = 1,int c = 1); // correct
調用帶有默認值的函數時,如果不指定帶有默認值的參數,則該參數自動被賦爲默認值
#include<iostream>
auto max(int a, int b = 1) {
return a > b ? a : b;
}
int main() {
std::cout << max(4, 2) << std::endl; // 傳入參數 b=2
std::cout << max(5) << std::endl; // 未對b傳參,b 默認爲1
return 0;
}
函數聲明有默認參數,函數實現時不需要帶默認參數
#include<iostream>
int max(int a, int b=5);
int main() {
std::cout << max(2,6) << std::endl;
std::cout << max(3) << std::endl;
return 0;
}
int max(int a, int b ) { // 如果此處給 b 賦默認值,報錯
return a > b ? a : b;
}
函數重載時,不允許定義默認參數
#include<iostream>
void max(int a = 1) {
std::cout<<a<<std::endl;
}
void max(double a = 1.4) {
std::cout << a << std::endl;
}
int main() {
max(3);
max(); // error,對重載函數的調用不明確
return 0;
}
4. 內聯函數
-
普通函數的優缺點
- 優點:易讀易維護
- 缺點:調用時有開銷
- 函數調用時:參數及部分 CPU 寄存器的內容進棧,控制流跳轉
- 函數返回時:返回值及寄存器值出棧,控制流跳轉
-
使用內聯函數
- 目的:減小函數調用開銷
- 方法:代碼插入到調用處
- 結果:程序變大
-
內聯函數的聲明
在普通函數前面加上 inline 關鍵字
inline int max(int a, int b) { return a > b ? a : b; }
-
調用內聯函數
和調用普通函數寫法相同
int x = max(3,6); int y = max(0,8);
-
內聯展開
編譯器實際在調用內聯函數的情況
int x = (3 > 6 ? 3 : 6); int y = (0 > 8 ? 0 : 8);
-
內聯函數的使用
常用場景:適用於頻繁調用的短函數
inline 關鍵字,只是對編譯器的一個請求,內聯函數是否展開,由編譯器決定