一、 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);
}