C++知識點隨筆(三):static、const、friend、inline
一、static
靜態成員屬性為什麼要在類外初始化?
靜態成員屬性之所以不能在建構函式內初始化,是因為建構函式必須要在定義物件的時候才會呼叫,而static變數在編譯的時候就建立了,所以要在類外通過類名作用域對static成員屬性初始化。
注意:sizeof()在C++中和C語言有不同,當我們:
cout << sizeof(//類名) << endl;
的時候,不是輸出這個類的大小,而是輸出定義一個這個類的物件需要申請多大的空間,所以如果這個類裡包含了靜態成員都不會計算在sizeof()內的,因為靜態成員一個類只有一份兒,所以的物件共用他們。
struct Node
{
int age;
char c;
};
class CPeople
{
public:
int pp;
static const int qq = 100; //靜態常量整形資料成員才能在類內初始化
static Node node[2];
static int num; // 靜態成員一定要在類外初始化
public: //相當於全域性變數,在編譯的時候就申請空間了,不用物件也能呼叫,(類名::)
CPeople()
{
pp = 100;
}
// 靜態成員函式:不能用普通的成員屬性,只能用 static 成員,因為沒有this指標
static void Show()
{
//cout << this->pp << endl;
cout << num << endl;
cout << "static::show" << endl;
}
};
Node CPeople::node[2] = {{123,'d'},{456,'y'}}; //靜態結構體陣列初始化
int CPeople::num = 123; //靜態成員的初始化
注意:靜態常量整形資料成員才能在類內初始化。所以short、long、char都可以,但是float、double不可以。
二、const
非靜態const成員屬性為什麼一定要在初始化列表裡進行初始化?
在C中我們知道#define進行預定義的某個數是被分配記憶體的,其檔案在編譯預處理過程中就會用定義好的資料去替代文中的符號。但是const卻是不一樣的,一般情況下編譯器也是不為const建立空間的,只是將這個定義的數字儲存在符號表中的。所以C++中const是在編譯的時候定義的,但是它的初始化可以在呼叫建構函式(也就是建立物件)的時候通過初始化列表的方式進行。呼叫建構函式的時候,首先是給該例項(類的具體物件)分配空間。使用初始化列表的話,就在分配空間的時候,同時將其空間初始化。但在建構函式的大括號裡,所有變(常)量的空間都已經分配好了,進行賦值操作。我們知道const是常量,只能進行初始化操作而不能進行賦值操作,所以必須在初始化列表中分配空間的同時進行初始化操作。
還有一個賦值次數,效率上的區別,初始化列表在物件初始化時對成員變數賦值一次,而使用建構函式內直接賦值的話,對成員變數賦值兩次,一次是物件構造是用預設值進行賦值,第二次是呼叫建構函式賦值。因為普通成員變數是否初始化都可以,而且允許賦值操作,所以普通成員變數既可以使用初始化列表又可以使用建構函式賦值。
參考:http://blog.csdn.net/zhouyelihua/article/details/23252667
const成員函式
void Show(/*const CPeople* this*/) const // 常函式,不能修改類中的成員屬性
{
//this->a = 100; //錯誤,因為 this 已經變成 const CPeople* this
}
常量型別的物件:
const CPeople pep;
只能呼叫常函式,普通函式用不了,因為我們知道成員函式在使用的時候要把物件的地址傳進去,而我們用常量物件呼叫普通成員變數的時候,相當於:
void AA(/*CPeople* this = const CPeople* ll*/)
{
a = 567;
}
一定會報錯的。而const成員函式的this已經變了,所以常量物件可以呼叫const成員函式。反過來普通物件可以呼叫常函式。
三、friend
friend class BB; // 友元類
friend void Show(CPeople pp); // 友元函式,可以讓這個東西用自己的private成員
無論是友元類還是被友元類,都不能繼承這個友元關係。友元的友元也不能使用。友元就是只限定這一個可以用。
類的封裝性問題
友元函式是破壞類的封裝性的最大殺手。我們在使用成員函式返回類的私有成員屬性的時候也是很危險的,如果一定要使用的話,就將返回值設為const。
四、inline
void AA() // 類內實現的都是行內函數(預設的)
{
cout << "AA" << endl;
}
/*inline */void BB(); // 不是內聯的
inline void BB(); // 內聯的
不過編譯器自己也會有判斷,其實宣告為inline只是對編譯器提出一個建議,建議編譯器進行內聯,而具體會不會內聯,由編譯器決定,編譯器會綜合考慮更方面因素來判斷要不要進行內聯。
內聯將函式程式碼直接在呼叫的地方展開,而函式呼叫是一個跳轉語句,通過函式指標跳轉到函式體的地址,執行完再回來,所以inline是一種用空間換時間的方法。
參考我的另一篇部落格:http://blog.csdn.net/u012300157/article/details/46763089
相關文章
- C++知識點隨筆(六):模板C++
- inline、const、mutable、this、staticinline
- C++知識點隨筆(五):虛繼承C++繼承
- 知識盲點 隨筆筆記筆記
- Python小知識點隨筆Python
- C/C++ Const 小知識C++
- C/C++【知識點筆記】C++筆記
- c++基礎知識(八)C/C++中修飾符const、extern、static、volatile的用法C++
- C++ static、const和static const變數 以及它們的初始化C++變數
- Flutter 知識梳理 (Dart) - Dart 中 static, final, const 區別FlutterDart
- mysql--平日點滴知識隨筆(待續)MySql
- var、let和const的知識點
- c++知識點C++
- Java常見知識點彙總(②)——StaticJava
- C/C++中Static和Const的作用C++
- C++中的static成員、static const成員和const成員的初始化C++
- C++基本知識點C++
- C++知識點隨筆(四):耦合問題、new和malloc、虛析構、多繼承C++繼承
- C/C++字串筆試知識點及例項C++字串筆試
- 【C++】 C++知識點總結C++
- 三、執行緒池知識點整理筆記執行緒筆記
- C++引用全部知識點C++
- C++學習筆記,知識點+程式碼測試C++筆記
- numpy知識點筆記筆記
- 生物知識點筆記筆記
- C++必知的幾個知識點C++
- 機器學習知識點整理(三)機器學習
- 架構知識點(三)架構
- C++知識點大彙總C++
- C++之static_cast,dynamic_cast,const_castC++AST
- 【知識點】inline函式、回撥函式、普通函式inline函式
- C++基礎知識筆記(1)筆記
- const,static,extern簡介
- extern、 const、static的理解
- 【知識點】C++的日誌框架C++框架
- C/C++重要知識點彙總C++
- vueX基礎知識點筆記Vue筆記
- 筆試題知識點總結筆試