1.vptr和vtbl
當(dāng)存在虛函數(shù)就會(huì)出現(xiàn)虛指針vptr指向虛函數(shù)所在位置vtbl
將vptr實(shí)現(xiàn)vtbl內(nèi)容翻譯為C:
(*p->vptr)n;
(* p->vptr[n])(p);
動(dòng)態(tài)綁定: 虛機(jī)制
1.指針
2.向上轉(zhuǎn)型保證安全
3.調(diào)用的是虛函數(shù)
2.this指針
[Template Method]
This->Serialize()實(shí)現(xiàn):
(*(this->vptr)[n])(this) -動(dòng)態(tài)綁定
3.動(dòng)態(tài)綁定
向上轉(zhuǎn)型 : 指針實(shí)現(xiàn)
如 B繼承A
B b;
A a = (A)b;
a.vfunc1(); 此時(shí),是靜態(tài)綁定,調(diào)用的是A類的vfunc1()
A* pa = new B;
pa->vfunc1(); 這里必須是動(dòng)態(tài)綁定啊,這里是指針.
pa = &b;
pa->vfunc1(); 這里依舊是動(dòng)態(tài)綁定.
4.const
void function() const { return data;}
const一般放在成員函數(shù)后頭,不放在全局函數(shù)后頭.
在成員函數(shù)后面加const是屬于簽名, 就是當(dāng)兩個(gè)成員函數(shù)傳參相同,那么加不加const也會(huì)被區(qū)分成兩個(gè)函數(shù).
在內(nèi)存共享的情況下, 要考慮內(nèi)容被更改時(shí)所產(chǎn)生的問(wèn)題.
class template::std::basic_string<..>有如下成員函數(shù):
charT operator[] (int n) const
{ //不必考慮COW}
reference operator[] (int n)
{ //必須考慮COW }
COW: Copy on write
所以這個(gè)類里面, 當(dāng)定義的是常量對(duì)象的時(shí)候,就會(huì)被強(qiáng)制調(diào)用const成員函數(shù), 當(dāng)定義的不是常量對(duì)象,那么就會(huì)調(diào)用非const成員函數(shù).
那么這里,當(dāng)是非常量對(duì)象時(shí), 也可以const成員函數(shù).
規(guī)則:當(dāng)成員函數(shù)的const和non-const版本都存在<>時(shí), const對(duì)象只能調(diào)用const版本, non-const對(duì)象只能調(diào)用non-const版本.
5.關(guān)于New,Delete
new對(duì)象的流程不能更改,但是實(shí)現(xiàn)過(guò)程中的函數(shù)可以被更改.
operator new
operator delete
6.重載::operator new, ::operator new[],::operator delete ,::operator delete[]
在全局當(dāng)中:
Note: 如果你重載了全局的操作符, 所以要額外小心.
這些重載不可以被聲明在一個(gè)namespace中.
//這里的函數(shù)是編譯器去調(diào)用, 所以size是編譯器給出.
void* operator new( size_t size )
{ return malloc(size);}
void* operator new[]( size_t size )
{ return malloc(size);}
void* operator delete(void* ptr )
{ free(ptr);}
void* operator delete[](void* ptr )
{ free(ptr);}
重載 member new , delete
在class里面重載new, delete
class foo{
public:
void* operator new(size_t size);
void operator delete(void *, size_t size); //size為可選
…….
};
那么你在:
foo *a = new foo;
delete a;
就會(huì)調(diào)用上面重載的函數(shù).
new[] , delete[] 也如此.
7.實(shí)例
當(dāng)類中重載了new , delete , 而又想調(diào)用全局的new , delete
可以這樣寫:
::delete a;
string類內(nèi)其實(shí)是一個(gè)指針.
當(dāng)創(chuàng)建一個(gè)數(shù)組的時(shí)候, 內(nèi)存當(dāng)中就會(huì)多分配一個(gè)指針,該指針用于保存當(dāng)前數(shù)組個(gè)數(shù).
8.重載new(),delete()示例
允許重載成員函數(shù)new(….) 其中參數(shù)中,必須有第一個(gè)且第一個(gè)必須是size_t size. 其余參數(shù)以new所指定的placement argument為初值.
Foo* p = new(300,’c’)Foo; //這里是三個(gè)參數(shù)
我們也可以重載類成員函數(shù) operator delete() ,寫出多個(gè)版本. 但他們絕不會(huì)被 通常所使用的delete調(diào)用.只有當(dāng)new所調(diào)用的ctor拋出 異常,才會(huì)調(diào)用這些重載版的operator delete(). 它們只能這樣被調(diào)用,主要用來(lái)歸還未能完全創(chuàng)建成功的對(duì)象所占用的內(nèi)存.
9.Basic_String使用new(extra)擴(kuò)充申請(qǐng)量
Basic_String在重載new()過(guò)后,傳遞了一個(gè)extra參數(shù), 用于后臺(tái)自動(dòng)多申請(qǐng)extra空間。