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++面向对象高级标称下课件
相关文章推荐
- 关于new和delete的编译器的内部实现---来自深度探索C++对象模型
- new_delete重载实现_boolan_第二门课_第二周_作业
- C++对象模型——new 和 delete 运算符(第六章)
- 动态对象创建(二)重载new和delete
- 深度探索c++对象模型之new和delete运算符介绍
- 极客班 c++(下)第二周学习笔记 ——重载 operator new & operator delete
- [Boolan] C++第五周 重载const,new,delete
- 位运算+引用+const+new/delete+内联函数、函数重载、函数缺省参数
- vc中new和delete操作符的重载
- c++ 中的重载全局new,delete
- ###struts模型驱动(必须new)能够封装【对象类型属性的属性】.页面传参错误导致的问题:HTTP Status 500 - could not execute statement;
- Item 50 重载new和delete
- 全局重载new和delete之后能否在STL中使用默认的new和delete
- 重载全局new,delete
- 重载全局new,delete
- 重载new和delete来检测内存泄漏
- C++的new、delete及其内存管理
- C++入门学习:new,delete及其和malloc,free的区别
- 【C/C++学院】0820-Nullptr/const对象/类指针引用以及mallocfree与newde/类重载运算符/QT加法重载/类的重载赋值运算/自增在前在后差别/赋值重载深浅拷贝/重载下标
- vc中new和delete操作符的重载