lxidea的 Boolan C++面向?qū)ο蟾呒?jí)編程(下)學(xué)習(xí)筆記(二)

本周介紹的是C++中末了剩下幾個(gè)重要概念,分別是

  1. 對(duì)象模型
  2. const
  3. new和delete重載

對(duì)象模型

對(duì)象模型里面包含了虛表和虛指針,這個(gè)又回到了以前分析過(guò)的對(duì)象在C++內(nèi)存中的分配。如果class里面有非虛函數(shù),那么這個(gè)非虛函數(shù)就會(huì)在編譯時(shí)作為靜態(tài)指針?lè)诺絚lass的內(nèi)存中去。class中如果有虛函數(shù),那么這個(gè)時(shí)候就會(huì)產(chǎn)生很多可能了。虛函數(shù)編譯時(shí)的指針不直接指向函數(shù)體本身,它指向一個(gè)表(虛表),這個(gè)虛表存儲(chǔ)了class中虛函數(shù)的個(gè)數(shù),在調(diào)用時(shí),會(huì)將this指針通過(guò)隱藏參數(shù)的方式傳遞進(jìn)來(lái)。每個(gè)帶有虛函數(shù)的class都會(huì)包含一根虛指針,這根指針就在這個(gè)類(lèi)內(nèi)存的頭部存放。調(diào)用的時(shí)候,碰到對(duì)虛函數(shù)的調(diào)用,就會(huì)到對(duì)象的頭部去找到指針?biāo)赶虻奶摫碇腥?,然后按順序查找到所需要調(diào)用的虛函數(shù)之后,將this指針傳遞進(jìn)去。

const

const關(guān)鍵字從前只是強(qiáng)調(diào),凡是不打算更改成員變量的成員函數(shù),都應(yīng)該加const。因?yàn)?,如果使用者聲明了一個(gè)const對(duì)象,只是調(diào)用這個(gè)對(duì)象的某些不更改數(shù)據(jù)的函數(shù)時(shí),編譯器就會(huì)報(bào)錯(cuò)。
但本周介紹的是更好更通用的一個(gè)用法,這里面隱藏著一個(gè)編譯器給定的一個(gè)規(guī)則。之前自己寫(xiě)的代碼好像也是這么寫(xiě)的,但并不知道為什么編譯能通過(guò)。
我是寫(xiě)過(guò)一個(gè)叫做vector的class

template <typename T, unsigned int N>
class vector {
    public:
        T &operator[](unsigned int index) {
            if (index >= 0 && index < N) return component[index];
            std::cout << "Error, index out of range";
            exit(1);
        };

        T operator[](unsigned int index) const {
            if (index >= 0 && index < N) return component[index];
            return T(0);
        };
    private:
        T component[N];
        unsigned int _dim;
    };

當(dāng)時(shí)只是想著用引用的時(shí)候會(huì)比較高效,但同時(shí)也要考慮到const對(duì)象的傳值,所以加了一個(gè)const的成員函數(shù)。
本周我們知道了如果一個(gè)class在編寫(xiě)的時(shí)候,同時(shí)提供了const和非const的成員函數(shù),那么編譯器會(huì)將const成員函數(shù)與const對(duì)象合用,將非const成員函數(shù)與非const對(duì)象合用。
那這件事就很好理解了。需要高效的時(shí)候傳引用來(lái)快速訪問(wèn)數(shù)據(jù),需要安全的時(shí)候傳const值來(lái)保護(hù)數(shù)據(jù)。嗯,完美。

new和delete重載

原來(lái)new和delete也可以重載。打開(kāi)了新世界的大門(mén)。
當(dāng)然,new操作會(huì)被編譯器自動(dòng)拆分為三個(gè)動(dòng)作

  1. 調(diào)用重載的new
  2. 將對(duì)象指針指向new回來(lái)的內(nèi)存地址
  3. 調(diào)用構(gòu)造函數(shù)

delete操作就分為兩步了

  1. 調(diào)用析構(gòu)函數(shù)
  2. 將對(duì)象指針傳給重載的delete

new操作符的重載必須寫(xiě)成class::operator new(size_t size);這種形式,而且第一個(gè)參數(shù)必須是size_t類(lèi)型。并且可以有多個(gè)不同參數(shù)列的new操作重載。與此對(duì)應(yīng)的,就可以有多個(gè)不同參數(shù)列的delete操作重載與new操作重載對(duì)應(yīng)。當(dāng)指定的new重載操作調(diào)用后遇到構(gòu)造函數(shù)執(zhí)行錯(cuò)誤,就會(huì)調(diào)用與之對(duì)應(yīng)的delete操作將申請(qǐng)回來(lái)的內(nèi)存還回去。
于是,new操作就給了我們一個(gè)偷偷更改分配內(nèi)存空間大小和如何返回內(nèi)存地址的方法了。用這個(gè)方法,可以自己編寫(xiě)內(nèi)存池,來(lái)動(dòng)態(tài)管理內(nèi)存。
也有一個(gè)辦法可以繞過(guò)class中重載的operator new(),那就是調(diào)用全局的::operator new()操作。
比如

Fruit *f = ::operator new Fruit();
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容