GeekBand-筆記-04

一、 vptr && vtable
1、基本上C++傳統(tǒng)意義上的多態(tài),就來(lái)自vptr和vtable
2、要深入理解,可以參看《深度探索C++對(duì)象模型》
3、另一種深入的方式是逆向成匯編,或者編譯器把cpp文件生成匯編文件
4、不怕累的話跟調(diào)試器也可以

二、 this pointer
沒(méi)有什么好說(shuō)的,參照侯老師的ppt應(yīng)該就可以了

三、 const
1、注意const關(guān)鍵字在定義時(shí)候,low-level const還是top-level const,定義的位置不同導(dǎo)致的語(yǔ)義不同
2、const對(duì)象和non-const對(duì)象對(duì)于成員函數(shù)調(diào)用的規(guī)則
3、轉(zhuǎn)載一段文字:(來(lái)自https://segmentfault.com/q/1010000002568358/a-1020000002573278
top-level const : const 修飾的是自身。
low-level const : const 修飾的是別人。

什么叫自身,什么叫別人?C++ 的世界里:

POD,類對(duì)象都只能是"自身"
指針可以是自身(指針本身),可以是別人(指向別人)。
引用沒(méi)有自身,只能是別人。(引用是別名)
所以,有以下幾個(gè)規(guī)律:

指針,可以是 top-level const,也可以是 low-level const。
引用只能是 low-level const。
指針何時(shí)是 top-level const,何時(shí)是 low-level const,請(qǐng)參考昨天回答的你的另一個(gè)問(wèn)題。
(const char *是 low-level, char * const 是 top-level.)

四、 new/delete重載
1、全局new和delete重載
a、 全局方式重載了new和delete之后,會(huì)贏得編譯器兩個(gè)警告,事實(shí)上C艸它爸爸在自己書(shū)里也有警告:“非特牛逼者勿要重載全局new和delete”。通常麻煩比功能多。
b、 普通的不帶參數(shù)的全局重載方式
void *operator new(size_t size)

{
//do something……
return malloc(size);
}

void operator delete(void *p)

{
//do something……

free(p);

}
c、 需要注意的是。重載全局的new和delete后,絕大多數(shù)class(重載有類成員new和delete的除外)會(huì)調(diào)用你重載后的版本,會(huì)帶來(lái)許多不可思議的問(wèn)題。慎重!慎重!慎重!
2、 作為類成員的new和delete
a、只對(duì)具體class生效
b、默認(rèn)情況下,是static的,不需要專門(mén)使用static關(guān)鍵字
c、因?yàn)槭莝tatic的成員函數(shù),所以不能使用this指針
d、因?yàn)槭莝tatic的成員函數(shù),所以也無(wú)法直接修改object的常規(guī)數(shù)據(jù)成員
e、在static成員函數(shù)里要修改object里的數(shù)據(jù)成員不是不可以,雖然無(wú)法直接修改,但是可以通過(guò)把object作為參數(shù)傳遞給static函數(shù),進(jìn)行修改
f、重載方式:
3、 帶參數(shù)的重載
a、 帶參數(shù)的重載形式如下:
void *operator new(size_t size, string fuck)

{

cout << "execute --> global fuck new, " << fuck << endl;

return malloc(size);

}

void *operator new[ ] (size_t size, string fuck)

{
cout << "execute --> global fuck new[], " << fuck << endl;

return malloc(size);

}

void operator delete(void *p, string fuck)

{

cout << "execute --> global fuck delete, " << fuck << endl;

free(p);

}

void operator delete[ ] (void *p, string fuck)

{

cout << "execute --> global fuck delete[], " << fuck << endl;

free(p);

}

b、 需要注意,帶參數(shù)的delete,是在構(gòu)造函數(shù)拋出異常的時(shí)候,才會(huì)被自動(dòng)調(diào)用。你無(wú)法直接調(diào)用一個(gè)呆參數(shù)的delete。
比如,定義一個(gè)class:

class theFuck {

int m_;

public:

theFuck(int m = 10) : m_(m)
{

cout << "now, we call theFuck's theFuck(), the object at " << this << endl;

// for call function : void operator delete(void *p, string fuck)

throw std::runtime_error(R"(SOME ERR...)");

}

~theFuck()
{

cout << "now, we call theFuck's ~theFuck(), the object at " << this << endl;

}

};

想看到帶參數(shù)的delete被執(zhí)行,你應(yīng)該在構(gòu)造里拋出一個(gè)異常。
然后這樣測(cè)試看效果:
void testTheFuck()
{
cout << endl << endl << "------------testTheFuck()------------" << endl;
theFuck *t = nullptr;
try {
t = new("@-@, oh my god!") theFuck();
} catch(std::runtime_error err) {
cout << "we have a exception, it's " << err.what() << endl;
}
if(t!=nullptr) {
cout << "execute --> delete t" << endl;
delete t;
}
cout << endl;
try {
theFuck tfk(100);
} catch(std::runtime_error err) {
cout << "we have a exception, it's " << err.what() << endl;
}
cout << "@-@ : bye bye, testApple()" << endl;
}

4、 new[ ] && delete[ ]
定義方式如new和delete,但是,new[ ] 要配套 delete[ ]
a、 重載方式
void *operator new[ ] (size_t size)

{
//do something……

return malloc(size);

}

void operator delete[ ] (void *p)

{
//do something……
free(p);

}

最后編輯于
?著作權(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)容