一、C++中的命名空間
C++中使用命名空間來解決在相同文件或范圍的同名變量問題,示例程序如下:
#include <iostream>
using namespace std;
#if 0
int g_count = 100;
int g_count = 200; //error,重命名錯誤
#endif
namespace stuname //定義命名空間stuname
{
const char *name = "zhangsan"; //定義命名空間中stuname的變量name
}
namespace homename //定義命名空間homename
{
const char *name = "xiaozhang"; //定義命名空間中homename的變量name
}
int main()
{
cout << "school : " << stuname::name << endl; //訪問stuname命名空間中的數據
cout << "homename : " << homename::name << endl; //訪問homename命名空間中的數據
}
二、C++標識符聲明使用的三種方法
C++的所有標識符都被定義在一個名叫std的namespace(命名空間)里,要想使用這些標識符,則必須先聲明,聲明有以下3種方法:
int main()
{
#if 0 //第1種:直接聲明使用
std::cout<<"hello world"<<std::endl;
#endif
#if 0 //第2種:先用using聲明要使用的標識符
using std::cout;
using std::endl;
cout<<"hello world"<<endl;
#endif
#if 1 //第3種:聲明使用標准命名空間中所有內容(即標識符)
using namespace std; //一般申明在頭文件后
cout<<"hello world"<<endl;
#endif
return 0;
}
三、自動類型轉換的四種情況
在C/C++中有以下四種情況會發生自動類型轉換:
#include <iostream>
#include <stdlib.h>
#include <string.h>
using namespace std;
int add(double num1,double num2)
{
return num1+num2;
}
int main()
{
//第1種:賦值
int i = 3.14; //轉換成int型
cout << "i=" << i << endl;
//第2種:運算時
double res = 4 + 3.14; //4運算前轉換成double型
cout << "res=" << res << endl;
//第3種: 函數調用實參與形參不一致時,自動轉換成形參類型
//第4種:當返回值類型與函數返回類型不一致時,自動轉換成函數返回類型
int result = add(2,3); //2,3轉換成double型,5再轉換成int型
cout << "result=" << result << endl;
return 0;
}
四、引用的使用
引用就是某一變量(目標)的一個別名,對引用的操作與對變量的直接操作完全一樣。
引用的聲明方法:類別標識符 &引用名 = 目標變量名。
示例程序如下所示:
int a;
int &ra=a; //定義引用ra,它是變量a的引用,即別名。
說明:
- &在此處不是取地址運算,而是標識作用。
- 聲明引用時,必須對其進行初始化。
- 引用聲明完畢后,相當於目標變量名有兩個名稱,即該目標原名稱和引用名,且不能再把該引用名作為其他變量的別名。
- 聲明一個引用,不是新定義了一個變量,它只表示該引用名是目標變量名的一個別名,他本身不是一種數據類型,因此引用本身不占存儲單元,系統也不給引用分配存儲單元。因此對引用求地址,就是對目標變量求地址。
- 不能建立數組的引用,因為數組是一個由若干個元素組成的集合,所以無法建立一個數組的別名。
五、C++內聯函數
C++中支持內聯函數,其目的是為了提高函數的執行效率,使用關鍵字 inline 可將函數指定為內聯函數,內聯函數通常就是將它在程序中的每個調用點上“內聯地”展開,假設我們將 max 定義為內聯函數:
inline int max(int a, int b)
{
return a > b ? a : b;
}
調用: cout<<max(a, b)<<endl;
,在編譯時展開為: cout<<(a > b ? a : b)<<endl
;從而消除了把 max寫成函數的額外執行開銷。
C++ 語言的函數內聯機制既具備宏函數的效率,又增加了安全性,而且可以自由操作類的數據成員。所以在 C++ 程序中,應該用內聯函數取代所有宏函數,“斷言 assert”恐怕是唯一的例外。
注意
- 代碼過長,多於3行,則編譯器會忽略 inline 限定符。
- 在類定義中的定義的函數都是內聯函數,即使沒有使用 inline 說明符。
- 函數內不能有復雜結構,例如for循環和開關語句。
六、C++多態相關
1、虛函數聲明如下:virtual ReturnType FunctionName(Parameter) 虛函數必須實現,如果不實現,編譯器將報錯,錯誤提示為:
error LNK****: unresolved external symbol "public: virtual void __thiscall ClassName::virtualFunctionName(void)"
2、虛函數是C++中用於實現多態(polymorphism)的機制。核心理念就是通過基類訪問派生類定義的函數。
3、在有動態分配堆上內存的時候,析構函數必須是虛函數,但沒有必要是純虛的。且基類的析構函數必須是虛函數,否則會析構不完全。
4、友元不是成員函數,只有成員函數才可以是虛擬的,因此友元不能是虛擬函數。但可以通過讓友元函數調用虛擬成員函數來解決友元的虛擬問題。
5、C++多態意味着調用成員函數時,會根據調用函數的對象的類型來執行不同的函數;形成多態必須具備三個條件:
- 必須存在繼承關系;
- 繼承關系必須有同名虛函數(其中虛函數是在基類中使用關鍵字Virtual聲明的函數,在派生類中重新定義基類中定義的虛函數時,會告訴編譯器不要靜態鏈接到該函數);
- 存在基類類型的指針或者引用,通過該指針或引用調用虛函數;
6、父類的虛函數或純虛函數在子類中依然是虛函數。有時我們並不希望父類的某個函數在子類中被重寫,在 C++11 及以后可以用關鍵字 final 來避免該函數再次被重寫。
例:
#include<iostream>
using namespace std;
class Base
{
public:
virtual void func()
{
cout<<"This is Base"<<endl;
}
};
class _Base:public Base
{
public:
void func() final//正確,func在Base中是虛函數
{
cout<<"This is _Base"<<endl;
}
};
class __Base:public _Base
{
/* public://不正確,func在_Base中已經不再是虛函數,不能再被重寫
void func()
{
cout<<"This is __Base"<<endl;
}*/
};
int main()
{
_Base a;
__Base b;
Base* ptr=&a;
ptr->func();
ptr=&b;
_Base* ptr2=&b; ptr->func();
ptr2->func();
}
/*
輸出結果:
This is _Base
This is _Base
This is _Base
*/
如果不希望一個類被繼承,也可以使用 final 關鍵字。
格式如下:
class Class_name final
{
...
};
則該類將不能被繼承。
七、C++ 函數傳遞參數的三種方式
(1)值傳遞
當進行值傳遞時,就是將實參的值復制到形參中,而形參和實參不是同一個存儲單元,所以函數調用結束后,實參的值不會發生改變。程序示例如下:
#include <iostream>
using namespace std;
void swap(int a,int b)
{
int temp;
temp=a;
a=b;
b=temp;
cout<<a<<","<<b<<endl; // 2,1
}
int main()
{
int x=l;
int y=2;
swap(x,y);
cout<<x<<", "<<y<<endl; // 1,2
return 0;
}
(2)指針傳遞
當進行指針傳遞時,形參是指針變量,實參是一個變量的地址,調用函數時,形參(指針變量)指向實參變量單元。這種方式還是 “值傳遞”,只不過實參的值是變量的地址而已。而在函數中改變的不是實參的值,而是實參地址所指向的變量的值。程序示例如下:
#include <iostream>
using namespace std;
void swap(int *a,int *b)
{
int temp;
temp=*a;
*a=*b;
*b=temp;
cout<<*a<<","«*b«endl; // 2,1
}
int main()
{
int x=l;
int y=2;
swap(&x,&y);
cout<<x<<","<<y<<endl; 2,1
return 0;
}
也就是說,在進行函數調用時,不僅交換了形參的值,而且交換了實參的值。
(3)引用傳遞
實參地址傳遞到形參,使形參的地址取實參的地址,從而使形參與實參共享同一單元的方式。程序代碼示例如下:
#include <iostream>
using namespace std;
void swap(int &a,int &b)
{
int temp;
temp=a;
a=b;
b=temp;
cout<<*a<<","<<*b<<endl; // 2,1
}
int main()
{
int x=l;
int y=2;
swap(x,y);
cout<<x<<","<<y<<endl; // 2,1
return 0;
}