P.S.感觉本周内容多是旧话重提,建立在之前的基础上进行深化。
1. 虚指针(vptr)和虚表(vtbl)
当类内有虚函数(virtual function)时,在类内会出现虚指针(vptr),用来指向相应的虚函数,而相应的虚函数,则形成对应的虚表(vtbl)。
在编译过程中,满足如下条件的函数调用将会被编译为动态绑定:
A. 必须通过指针来调用
B. 指针必须向上转型
C. 调用的必须是虚函数
2. 成员函数的const
成员函数在设计初始时就知道是否需要修改类内的内容,后面设计时必须在不准备修改数据的成员函数签名末尾加上const
。
!! const object常量只能调用const member function
!! 当成员函数的const和non-const版本同时存在,const object只能调用const版本,non-const object只会调用non-const版本。
P.S. 之前使用中发现,const member function中所有类内数据全都只能作为常量(const object)使用。
3. 关于new、delete
例1:
String* ps = new String("Hello");
上述代码将会被编译器转化为:
String* ps;
void* mem = operator new(sizeof(String));
ps = static_cast<String*>(mem);
ps = String::String("Hello");
例2:
String* ps = new String("Hello");
…
delete ps;
上述代码将会被编译器转化为:
String::~String(ps);
operator delete(ps);
4. 重载::operator new,::operator delete
::operator new[],::operator delete[]
例3:
void* myAlloc(size_t size)
{
return malloc(size);
}
void myFree(void* ptr)
{
return free(ptr);
}
inline void* operator new(size_t size)
{
cout << "jjhou global new() \n";
return myAlloc(size);
}
inline void* operator new[](size_t size)
{
cout << "jjhou global new[]() \n";
return myAlloc(size);
}
inline void operator delete(void* ptr)
{
cout << "jjhou global delete() \n";
return myFree(ptr);
}
inline void operator delete[](void* ptr)
{
cout << "jjhou global delete[]() \n";
return myFree(ptr);
}
5. 重载member operator new/delete/new[]/delete[]
例4:
class Foo
{
public:
int _id;
long _data;
string _str;
public:
Foo() : _id(0) { cout << "default ctor.this=" << this << "id=" << _id << endl; }
Foo(int i) :_id(i) { cout << "ctor.this=" << this << "id=" << _id << endl; }
//virtual
~Foo() { cout << "dtor.this=" << this << "id=" << _id << endl; }
static void* operator new(size_t size);
static void operator delete(void* pdead, size_t size);
static void* operator new[](size_t size);
static void operator delete[](void* pdead, size_t size);
};
void * Foo::operator new(size_t size)
{
Foo* p = (Foo*)(malloc(size));
cout << ……
return p;
}
void Foo::operator delete(void * pdead, size_t size)
{
cout << ……
free(pdead);
}
void * Foo::operator new[](size_t size)
{
Foo* p = (Foo*)(malloc(size));
cout << ……
return p;
}
void Foo::operator delete[](void * pdead, size_t size)
{
cout << ……
free(pdead);
}
6. 重载new(),delete()
应用较少,贴图。