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