本章主要內容: 1)函數重載 2)C++調用C代碼 3)new/delete關鍵字實現動態記憶體分配 4)namespace命名空間 大家都知道,在生活中,動詞和不同的名詞搭配一起,意義都會大有不同,比如”玩”: 玩游戲 玩卡牌 玩足球 所以在C++中,便出現了函數重載(JAVA,c#等語言都有函數重 ...
本章主要內容:
- 1)函數重載
- 2)C++調用C代碼
- 3)new/delete關鍵字實現動態記憶體分配
- 4)namespace命名空間
大家都知道,在生活中,動詞和不同的名詞搭配一起,意義都會大有不同,比如”玩”:
- 玩游戲
- 玩卡牌
- 玩足球
所以在C++中,便出現了函數重載(JAVA,c#等語言都有函數重載)
1.函數重載(overload)
表示有多個相同的函數名(類似上面的”玩”),但是參數表不同(類似上面的動詞)
參數表不同主要有以下幾種
- 1) 參數個數不同
- 2) 參數類型不同
- 3) 參數順序不同
1.1舉個慄子
#include <stdio.h> int func(char *str) //func1 { printf("str=%s\n",str); } int func(int a) //func2 { printf("a=%d\n",a); } int func(int a,int b) //func3 { printf("a*b =%d\n",a*b); } int main() { char s[10]="hello"; func(s); func(10); func(5,5); }
輸出結果:
str=hello a=10 a*b =25
通過上個慄子可以看到,函數名相同,參數不同,而意義卻大有不同.
1.2那這些重載函數的入口地址是否相同
修改上面慄子的main()函數,如下圖所示:
可以看到輸出結果,每個函數的入口地址都不一樣(重載函數的入口地址,必須使用強制轉換來獲取)
也可以通過nm命令來查看符號表,如下圖所示:
註意:
- 重載函數需要避免使用參數預設值
- 調用重載函數時,只會匹配函數參數表,與函數返回值無關
- 函數重載必鬚髮生在同一個作用域中
- 重載函數的入口地址,不能直接通過函數名來獲取
2.C++與C代碼相互調用
當C++想調用C里的某個函數時,則使用extern “C”
還是舉個慄子,通過C++調用C裡面的add()函數
1) 首先創建3個文件
add.c代碼如下:
#include "add.h" int add(int a,int b) { return a+b; }
add.h代碼如下:
int add(int a,int b);
main.cpp代碼如下:
#include <stdio.h> #ifdef __cplusplus extern "C" //通過C方式來編譯add.h,也就是add()函數 { #include "add.h" } #endif int main() { printf("%d \n",add(1,3)); return 0; }
main.cpp里的__cplusplus巨集是C++編譯器自帶的,而extern "C"只有C++里才有定義.
所以通過__cplusplus巨集判斷,可以使main.cpp在C或C++編譯器下都能編譯運行.
2)編譯運行:
gcc -c add.c //生成add.o文件 g++ -o main main.cpp add.o //生成main可執行文件 ./main
3)輸出結果:
3. C++中的動態記憶體分配
3.1 回顧C:
在C語言中,大家都知道使用malloc()和free(),比如:
int *p = malloc(10*sizeof(int)); //申請10個int型空間 if(p) { ... ... free(p); }
從上面慄子,可以看到C是通過庫函數完成記憶體分配的
3.2而在C++中,則通過new關鍵字進行記憶體申請,delete關鍵字進行記憶體釋放,比如:
- Type: 指數據類型,比如int,char,float等
- N: 指申請的數組個數大小
除了上圖例子外,new關鍵字還可以通過分配並初始化(類似calloc()函數)
例如:
int *p1= new int(1); //動態分配一個int空間給p1,並賦值為1 float *p2=new float(2.0f); //2.0後面加f,表示2.0是個float類型 char *p3=new char('c');
註意:
- 釋放數組的空間時,必須使用delete[],避免記憶體泄漏
4.C++中的命名空間(namespace)
4.1回顧C:
大家都知道,在C語言中,當編譯多個C文件時,可能會遇到同名全局標識符的錯誤,這是因為C語言中的所有全局標識符都是共用同一個作用域
4.2所以C++中便提出命名空間(namespace)的概念
- 命名空間會將全局作用域分成不同部分的命令空間,可以將類,對象,函數等聚集在一個namespace里
- 不同命名空間中的標識符可以同名
- 命名空間可以相互嵌套,也就是說A命令空間里可以再次定義B命令空間
- 在C++中,全局作用域也叫預設命名空間
4.3命名空間(namespace)的使用
1)定義一個命名空間:
namespace name //定義一個命名空間,名為name { int varialbe; //... ... }
2)使用整個命名空間:
using namespace name;
3)使用整個命名空間中的變數:
::varialbe;
4)使用某個命名空間中的變數:
using name::variable //使用name空間里的variable變數
4.4 舉個慄子
#include <stdio.h> namespace First //定義First命名空間 { int i = 0; } namespace Second //定義Second命名空間 { int i = 1;namespace Internal //在Second里,再次定義一個Internal空間(實現嵌套) { struct Position { int x; int y; }; } } int main() { using namespace First; //使用First整個命名空間,成為該main()的預設空間 using Second::Internal::Position; //使用Second->Internal空間里的Position結構體 printf("First::i = %d\n", i); printf("Second::i = %d\n", Second::i); Position p = {2, 3}; printf("p.x = %d\n", p.x); printf("p.y = %d\n", p.y); return 0; }
輸出結果:
First::i = 0 Second::i = 1 p.x = 2 p.y = 3
未完待續,下章繼續學習C++中的強制轉換