Boolan_c++第5周笔记

一、对象模型:关于vptr(虚指针)和vptl(virtual table)

类对象占用多少内存,要看其含有的数据data

子类中有父类的数据成员

只要类中有虚函数,对象中就含有指针(有几个虚函数,就含有几个虚指针);子类继承父类会连同指针一起继承,继承函数是继承调用权,所以父类有指针,子类一定有。

Boolan_c++第5周笔记_第1张图片
vtbl中放的都是虚指针

三个类:ABC继承关系,A是父类,定义一个容器存放不同的形状  listmylist; (容器中放不同类型,所以要定义指针,指针指向父类,以后可以指向任意子类) 通过指针指向各个不同类中的函数

Boolan_c++第5周笔记_第2张图片
Boolan_c++第5周笔记_第3张图片
draw必须是虚函数

c++编译器看到函数调用,是静态/动态绑定:

1.静态绑定  call xxx,一定调用到某地址

2.动态绑定(复合三个条件):1)通过指针调用 2)指针向上转型,new的是一只猪,声明时是指向动物 3)调用的是虚函数   //看指针指向哪里

多态:listmylist 指针声明是指向A,实际指向不同的东西(但都是A的子类),指针有很多形态


二、对象模型:关于this

1. 通过一个对象来调用一个函数,对象的地址就是this

虚函数两种用法:1)多态     2)模版

子类的对象可以调用父类函数

Boolan_c++第5周笔记_第4张图片
myDoc的地址就是this

三、对象模型:关于Dynamic Binding

通过对象调用的虚函数是静态的

class A; class B;   A是B的父类,

A* pa= new B;    //向上转型,new出来是B,类型是A 

pa->vfunc1();     //是动态绑定

Boolan_c++第5周笔记_第5张图片
c语言中写法,通过p指向虚指针vptr--找到虚表,取出其中第n个,当成函数指针去调用,通过(p)调用,p相当于this指针

四、const

1. 常成员函数

double real() const { return re; }   //const在这个位置,只可以是放在成员函数后面;const放在这个位置是要告诉编译器这个成员函数不改变class的data(成员函数是用来操作data的)

常量对象只可调用常成员函数

const String str("hello world");

str.print();   //print定义时要加const

COW:copy on write  <没听懂!!!>

Boolan_c++第5周笔记_第6张图片

当成员函数const和non-const版本同时存在,const object只能调用const版本,non-const object只能调用non-const版本。

五、关于new,delete

new先分配内存,再调用构造函数;delete先调用析构函数,再释放内存

六、重载 ::operator new, ::operator delete, ::operator new[ ], ::operator delete[ ]

::表示全局的。  

///他们不可以被声明在同一个namespace内

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"; myFree(ptr); }

inline void operator delete[ ](void* ptr)

{ cout << "jjhou global delete[ ]()\n"; myFree(ptr); }


七、重载new(),delete()

我们可以重载class member operator new(),写出多个版本,每一个版本都必须有独特的参数列,其中重载new第一个参数必须是size_t, 其余参数以new所指定的placement arguments为初值。出现于new(......)括号里是placement arguments

Foo* pf = new(300,'c') Foo;

也可以重载class member operator delete(),写出多个版本。但不会被delete调用。只有当new所调用的ctor抛出异常,才会调用这些重载版的operateor delete()

operator new分配内存后调用构造函数发生异常,(没成功要把刚刚分配的内存释放),要调用对应的operator delete

即使operator delete(...)未能一一对应operator new(...),编译器不会报错

八、basic_string使用new(extra)扩充申请量

你可能感兴趣的:(Boolan_c++第5周笔记)