您的位置:首页 > 编程语言 > C语言/C++

boolan C++高级编程下(第二周)对象模型、const、new和delete及其重载

2018-02-04 23:49 211 查看

1.对象模型:虚指针和虚表:vptr和vtbl



1.虚指针和虚表是存在于底层的东西;

2.子类的对象有父类的成分,当一个类有虚函数的时候,这个对象就有一根指针,带有虚函数的对象的大小等于所有数据所占用的空间再加4.如上图所示,b是a的子类,b的数据除了自己定义的m_data3、还包括a类的指针和两个数据。子类除了继承a 的数据还继承父类的虚函数调用权,父类有虚函数,子类一定有虚函数。b类继承了a类的两个虚函数,其中vfunc1被改写;除此之外还定义了自己的函数func2,b一共有3个函数。c也是同理。因此,3个类一共定义8个函数,4个虚函数和4个非虚函数。

3.假设用指针P去调用c类的vfunc1()。则用动态绑定去实现,使用虚指针vptr去vtbl中找相应函数的指针,在找到相应的函数。而不使用静态绑定的形式(call×××)

对于一个PowerPoint的实现:



调用动作被编译为动态绑定的条件:

1.必须是通过指针调用

2.指针是向上转型

3.调用的是虚函数

2.关于this



this是一个指针也是一种观念,这个例子的this指向myDoc的地址。其满足动态绑定的条件,因此在运行过程中触发动态绑定,在调用vS(virtual Serialise())函数时,指向子类的vS函数。

3.关于const



1.Const只能放在成员函数的后头,一般的全局函数是不可以在那个位置加const的。

2.const放在那里的意思是告诉编译器,我这个函数不打算改变数据。不加const的意思是可能会改变data,不保证不改变data。

3.对象调用函数的时候,函数可能是const,也可能不是const。


4.关于new和delete



new和delete表达式得工作机理:
例子:

string* sp=new string("hello");
string* arr=new string[10];第一步:new表达式调用一个名为operator new的标准库函数,该函数分配一块足够大、原始、未命名的内存空间;
第二步:编译器运行相应的构造函数以构造这些对象,并赋初值;

第三步:对象被分配了空间并构造完成,返回一个指向该对象的指针。

delete sp;
delete [] arr;第一步:对指针所指的数组中的元素执行对应的析构函数;
第二步:编译器调用名为operator delete的标准函数释放内存。







1.应用程序可以再全局作用域定义operator new和operator delete函数,也可以将他们定义为成员函数,当编译器发现一条new或delete函数表达式,将在程序中查找可供调用的operator函数。如果被分配的对象是累类型,则编译器首先在类及其基类的作用域中查找。此时如果该类含有operator new成员或者operator delete成员,相应的表达式将调用这些成员。否则,编译器在全局作用域查找匹配的函数。

2.可以使用作用域运算符令new表达式或者delete表达式忽略定义在类中的函数,直接执行全局作用域中的版本。如:::new只在全局作用域中查找匹配的operator new函数,::delete与之类似。

3.标准库定义了operator new和operator delete函数的8个重载版本,其中前4个可能抛出bad_alloc异常,后四个则不会。

可能抛出异常的版本:

void *operator new(size_t);
void *operator new[] (size_t);
void *operator delete (void*) noexcept;
void *operator delete[] (void*) noexcept;


不会抛出异常的版本:

void *operator new(size_t,nothrow_t&) noexcept;
void *operator new[] (size_t,nothrow_t&) noexcept;
void *operator delete (void*, nothrow_t&) noexcept;
void *operator delete[] (void*,nothrow_t&) noexcept;应用程序可以自定义上边函数版本中的任意一个,但是自定义的版本必须位于全局作用域或者类作用域中。
对于operator new或者operator new[]来说,其返回值类型必须void*。

对于operator delete或者operator delete[]来说,其返回值类型必须void。

参考:

《c++primer中文版》(第五版)

boolan C++面向对象高级标称下课件
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: