C++的靜態聯編和靜態聯編。本站提示廣大學習愛好者:(C++的靜態聯編和靜態聯編)文章只能為提供參考,不一定能成為您想要的結果。以下是C++的靜態聯編和靜態聯編正文
比來在看析構函數的內容,看到一些講的比擬好的文章,這裡我也有了一些我本身的領會,在這裡一並記載一下。
聯編是指一個盤算機法式本身彼此聯系關系的進程,在這個聯編進程中,須要肯定法式中的 操作挪用(函數挪用) 與 履行該操作(函數) 的代碼段之間的映照關系。
意思就是這個函數的完成有多種,聯編就是把挪用和對應的完成停止映照的操作。
依照聯編停止的階段分歧,可分為靜態聯編和靜態聯編。
靜態聯編
靜態聯編任務是在法式編譯銜接階段停止的,這類聯編又稱為晚期聯編,由於這類聯編其實 法式開端運轉之前 完成的。在法式編譯階段停止的這類聯編在編譯時就處理了法式的操作挪用與履行該操作代碼間的關系。
靜態聯編
編譯法式在編譯階段其實不能確實地指點將要挪用的函數,只要在法式履行時能力肯定將要挪用的函數,為此要確實地指點將要挪用的函數,請求聯編任務在法式運轉時停止,這類在 法式運轉時停止的 聯編任務被稱為靜態聯編。 C++中,靜態聯編是在虛函數的支撐下完成的 。
靜態聯編和靜態聯編都是屬於多態性的,他們在分歧的階段對分歧的完成停止分歧的選擇。
靜態聯編須要虛函數的支撐,這是由於虛函數的任務道理決議的,而恰是由於應用了虛函數來完成靜態聯編,也讓靜態聯編的效力略低於靜態聯編。平日,編譯器處置虛函數的辦法是: 給每一個對象添加一個隱蔽成員,隱蔽成員保留了一個指向函數地址數組的指針 ,這個數組就是虛函數表(virtual function table, vtbl)。虛函數表中存儲了為類對象停止聲明的虛函數的地址,挪用虛函數時,法式將檢查存儲在對象中的vtbl地址,然後轉向響應的函數地址表,假如應用類聲明中界說的第一個虛函數,則法式將應用數組中的第一個函數地址,並履行具有該地址的函數,假如應用類聲明中的第三個虛函數,法式將應用地址位數組中第三個元素的函數。
虛函數這個概念是C++的精髓之一。碰到虛函數時要留意:
界說一個函數為虛函數,不代表函數為不被完成的函數(可以有本身的完成)
界說他位虛函數是為了許可用基類的指針來挪用子類的這個函數(供給了基類挪用子類函數的方法)
界說一個函數為純虛函數,才代表函數沒有被完成(聲明前面接=0 virtual func() = 0 此時派生類必需要完成此虛函數)
具有純虛函數的類是 籠統類 ,不克不及用於生成對象(即不克不及實例化),只能派生,他派生的類假如沒有完成純虛函數,那末他的派生類照樣籠統函數。
虛析構函數
虛析構函數望文生義就是將析構函數界說為虛函數。假如我們在派生平分配了內存空間,然則基類的析構函數不是虛析構函數,就會產生內存洩露。先看一個例子
#include <iostream> using namespace std; class Base { public: Base(){ data = new char[10];} ~Base(){ cout << "destroying Base data[]\n";delete []data;} private: char *data; }; class Derive: public Base { public: Derive(){ D_data = new char[10];} ~Derive(){ cout << "destroying Derive data[]\n";delete []D_data;} private: char *D_data; }; int main() { Base *basePtr = new Derive(); delete basePtr; return 0; }
輸入成果:
$ ./a.out destroying Base data[]
在這個例子中,派生類的析構函數並沒有被挪用,這在年夜的項目中就是一個災害。究其緣由是我們在main函數中界說了一個Base的指針,當我們delete一個靜態分派的Base指針時,Base指針此時卻指向了Derive類型的對象,但編譯器照樣依照Base類型挪用了析構函數,沒有履行Derive類型的虛析構函數。修正Base類的析構函數為虛析構函數便可以確保履行准確的析構函數版本。
最初總結一下關於虛函數的一些罕見成績: