C++系列
文章目錄
- C++系列
- 前言
- 一、命名空間
- 二、缺省參數
- 2.1、缺省參數概念
- 2.2、 缺省參數分類
- 2.2.1、全缺省參數
- 2.2.2、半缺省參數
- 2.3、缺省參數的特點
- 三、函數重載
- 3.1、函數重載概念
- 3.2、構成函數重載的條件
- 3.2.1、參數類型不同
- 3.2.2、參數個數不同
- 3.2.3、參數類型順序不同
前言
在學習C++之前,首先我們要知道—C++是在C的基礎之上,容納進去了面向對象編程思想,并增加了許多有用的庫,以及編程范式等。這篇文章可以幫助我們了解c++是如何:
- 補充C語言語法的不足,以及C++是如何對C語言設計不合理的地方進行優化的。
- 為后續類和對象學習打基礎。
一、命名空間
隨著c語言的不斷發展和完善,C語言庫函數和關鍵字的定義,越來越多,這些變量、函數和類的名稱將都存在于全局作用域中,而在我們編寫程序時定義的函數、變量有時就會和庫中所定義的發生沖突,如:
#include <stdio.h>
#include <stdlib.h>
int rand = 10;
// C語言沒辦法解決類似這樣的命名沖突問題,所以C++提出了namespace來解決
int main()
{printf("%d\n", rand);return 0;
}
注:這里的報錯就是因為在庫中有一個rand()函數,與我們定義的rand變量名字沖突了。
C語言沒有辦法很好的解決這類問題,c++便提供了命名空間的方法,命名空間的目的是對標識符的名稱進行本地化,以避免命名沖突或名字污染,namespace關鍵字的出現就是針對這種問題的。
命名空間定義:
定義命名空間,需要使用到namespace關鍵字,后面跟命名空間的名字,然后接一對{}即可,{}中即為命名空間的成員,如:
namespace ltn
{// 命名空間中可以定義變量/函數/類型int rand = 10;int Add(int left, int right){return left + right;}
}
注意:一個命名空間就定義了一個新的作用域,命名空間中的所有內容都局限于該命名空間中
現在命名沖突的問題我們解決了,但是當你嘗試對類中的函數進行調用時又會出現問題,如:
namespace ltn
{int rand = 10;int Add(int left, int right){return left+right;}
}
int main()
{Add(1, 1);return 0;
}
這是因為對于這個命名空間中所定義函數、變量等,我們是不可以直接訪問的,需要配合“::”域作用符,指定域來進行訪問,如:
namespace ltn
{int rand = 10;int Add(int left, int right){return left+right;}
}
int main()
{printf("%d\n", ltn::rand);ltn::Add(1, 1);return 0;
}
如果我們不指定域,編譯器首先會去局部查找,其次會去全局域查找,并不會去我們所定義的命名空間中查找,這一點會在后面驗證。
在我們編寫c++代碼時,往往會在代碼中,編寫這樣一段代碼“using namespace std;”這里的std就是我們標準庫所在的域,而這句代碼的意思就是,將這個命名空間展開(權限放開),使我們在使用庫中定義的函數、關鍵字時,不在受域限制,我們可以通過自己定義的命名空間來驗證這里的問題,如:
在不指定命名空間時程序是無法編譯的,接下來我們展開ltn這個命名空間:
#include <stdio.h>
#include <stdlib.h>
namespace ltn
{int rand = 0;int Add(int left, int right){return left + right;}
}
int main()
{Add(1, 1);return 0;
}
對上面個這中情況,我們如果展開命名空間,rand變量就會和庫中的rand()函數沖突,如果不展開每次都要指定域訪問,又有點麻煩,這時我們就可以將
命名空間中我們經常使用的函數、變量具體引,如:
還以一點,當我們在兩個不同的文件中,定義了相同的命名空間他們是會自動合并的,例:
namespace ltn
{int add(int x,int y){printf("add\n");return 0;}
}
在test.h文件中定義一個和test.c相同的命名空間,這是我們只需要將test.c中的命名空間展開test.h命名空間中的add函數一樣可以使用。
二、缺省參數
2.1、缺省參數概念
缺省參數是聲明或定義函數時為函數的參數指定一個缺省值。在調用該函數時,如果沒有指定實參,則采用該形參的缺省值,否則使用指定的實參。
void Func(int a = 0)
{cout<<a<<endl;
}
int main()
{Func(); // 沒有傳參時,使用參數的默認值Func(10); // 傳參時,使用指定的實參
return 0;
}
2.2、 缺省參數分類
2.2.1、全缺省參數
void Func(int a = 10, int b = 20, int c = 30)
{cout << "a = " << a << endl;cout << "b = " << b << endl;cout << "c = " << c << endl;
}
int main()
{Func();cout <<"-----------------" << endl;Func(1);cout << "-----------------" << endl;Func(1,2);cout << "-----------------" << endl;Func(1,2,3);return 0;
}
但我們使用全缺省時,我們可以選擇性給函數傳遞數據。
2.2.2、半缺省參數
void Func(int a, int b = 10, int c = 20)
{cout << "a = " << a << endl;cout << "b = " << b << endl;cout << "c = " << c << endl;
}
int main()
{Func(1);cout << "-----------------" << endl;Func(1,2);cout << "-----------------" << endl;Func(1,2,3);return 0;
}
半缺省函數需要注意的是:
- 半缺省參數必須從右往左依次缺省,不能間隔著給
- 半缺省參數在調用是,我們傳遞的參數是從左到右依次匹配的
2.3、缺省參數的特點
1、缺省參數不能在函數聲明和定義中同時出現:
語法規定,當我們對函數進項聲明和定義分離時,缺省參數不可同時存在,如果同時存在,而兩個位置提供的值不同,那編譯器就無法確定到底該用哪個缺省值。
2、 缺省值必須是常量或者全局變量
這個大家自己驗證吧。
三、函數重載
3.1、函數重載概念
函數重載:是函數的一種特殊情況,C++允許在同一作用域中聲明幾個功能類似的同名函數,這些同名函數的形參列表(參數個數 或 類型 或 類型順序)不同,常用來處理實現功能類似數據類型不同的問題
3.2、構成函數重載的條件
構成重載的函數在調用時編譯器會根據我們傳遞的參數,匹配調用合適的函數。
3.2.1、參數類型不同
int Add(int left, int right)
{cout << "int Add(int left, int right)" << endl;return left + right;
}
double Add(double left, double right)
{cout << "double Add(double left, double right)" << endl;return left + right;
}
int main()
{Add(1,1);Add(1.1, 1.2);return 0;
}
程序執行時,編譯器自動匹配合適的函數進行調用。
3.2.2、參數個數不同
void f()
{cout << "f()" << endl;
}
void f(int a)
{cout << "f(int a)" << endl;
}
int main()
{f();f(1);return 0;
}
這里要注意的是,我們上面提到的缺省參數如果像下面這樣使用,會造成二義性的問題:
3.2.3、參數類型順序不同
需要注意的是,這里說的參數類型順序不同指的是不同類型的參數。
void f(int a, char b)
{cout << "f(int a,char b)" << endl;
}
void f(char b, int a)
{cout << "f(char b, int a)" << endl;
}
int main()
{f(10, 'a');f('a', 10);return 0;
}
至于c++是如何支持函數重載的,大家感興趣可以搜一下c++中函數名命名規則。