1.关于vptr和vtbl
对象内存的问题,结合上个星期的题目,当子类继承父类的时候,子类会继承父类的私有成员变量,当一个类有虚拟函数的时候,函数会多一个虚拟指针,用来指向虚拟表,当父类为虚拟类的时候,它的子类也必定是虚拟类。所以继承函数其实是继承了函数的调用权。
(*(p->vptr)[n])(p),这个表达式是当我们调用某个虚函数的时候编译器翻译成的语言表达式。其中n表示的时候虚函数表中调用的函数的位置。
多态
指针的声明是父类的大小,在具体对象的时候指向不同的子类,达到了指针大小相同,但可以调用不同子类中的函数,达到了取不同对象中相同的部分形成数组的目的。
2.关于this
谁调用这个函数谁就是this,在设计模式template method模板方法中,提前写好所有部分,但其中用到了一个虚函数,你只需要在子类中重载该虚函数,就可以达到想要的效果。
3.关于dynamic binding动态绑定
A a = (A)b;
a.vfunc1();
这是静态调用
A* pa = new B;
Pa->vfunc1();
动态绑定的三个条件,指针,向上转换,调用了虚函数。
4.const
const member function常量成员函数
在函数的后头加const意思是修饰成员函数不会改变data members
这里只有一种情况会出错,当声明的对象本身是const的时候,他调用了non-const member functions会出错。而non-const member
function可以调用const member function,反之则不行,即const member function只能调用const member functions.
Char T
Operator[](size_type pos) const {}
reference
Operator[] (size_type pos) {}
Const不需要考虑copy on write
拷贝的时候,他们可以共享内容,当一个人改变的时候,单独拷贝一份给它,如果调用中括号的人是一个常量字符串,他绝对不会做cow
当成员函数的const和non-const版本同时存在的时候,const
obj只会调用const版本,non-const obj只会调用non-obj版本。
5.关于new delete
之前讲过,new分为三步,首先分配内存,在调用ctor
delete分为两步,首先调用dtor,再释放内存。
6.重载operator new和operator delete
分为两部分,包括重载全局的operator new和operator delete以及重载成员的operator new, operator delete
当没有重载过成员的上述两个函数,New会自动调用全局的::operator new,还有一种强制调用全局的方法。
讲到了数组里面有对象的大小,这个数组的大小应该是所有对象大小的和加上一开始有一个常数来表示该数组有几个元素。
在重载class member operator new的时候,我们可以写出多个版本,第一个参数必须是size_t,其余的用new中制定的placement argument为初值。我们也可以重载class member operator delete(),并写出多个版本,但他们不会被delete调用,只有当new所调用的ctor有异常的时候,我们需要释放之前分配的内存,就会调用对应的operator delete,因为我们在delete的时候不会加argument
也不是所有的operator new都要写对应的delete,这时候你的意思是放弃处理这种异常。