深入探索C++对象模型
1、C struct在c++当中的一个合理用途,是当你要传递“一个复杂的class object的全部或者部分”到某个C函数当中去的时候,,struct申明可以将数据封装起来,并保证拥有与C兼容的空间布局。
2、yoqi会被释放吗?如果yoqi被释放了,他的虚表还存在吗?虚表的地址存放在对象当中的什么位置呢?按照书当中的说明,该地址一般放置在基地址的尾端?


上面两个case的拷贝构造的汇编代码是什么?需要进行测试!
3、
Shape:Shape()
{
//vptr必须在使用者的代码执行之前先设定妥当
_vptr__shape = _vtbl_Shape;
//owo,memset会将vptr清0
memset(this,0,sizeof(shape));
}
4、一些实际工作当中的技术问题,我们总该以最简单的demo去进行验证,才能加深理解。
5、方式2新的编译器会对其进行优化吗?
//方式1:比较好的实现方式
Word::Word:_name(0)
{
_cnt= 0;
}
//方式2: 多一层拷贝
Word::Word
{
_name =0;
}
6、编译器会按照class中member的申明顺序一一操作intializelist ,以适当的顺序在constructor之内安插初始化操作,并且在任何explicit user code之前。
7、name-mangling:名称的特殊处理

8、汇编代码进行测试!一个经由对象而不是指针调用的virtual function的调用操作,可以在编译期被决议(resolved)完成一样。

9、Slot存储RTTI的信息,是如何实现的,通过汇编代码验证相关的实现!

class Point2D { public : Point2D(int x0, int y0) { x = x0; y = y0; } virtual int distance(int x0, int y0) { return (x - x0) ^ 2 + (y - y0) ^ 2; } virtual const char * Name() { return "Point2D"; } private: int x; int y; static int c; }; int Point2D::c = 0; class Point3D :public virtual Point2D { public: Point3D(int x0, int y0, int z0): Point2D(x0,y0) { z = z0; } virtual int distance(int x0, int y0, int z0) { return Point2D::distance(x0, y0) + (z - z0) ^ 2; } virtual const char * Name() { return "Point3D"; } private: int z; }; int main() { Point3D st3D(3, 4, 5); Point2D *p2D; p2D = &st3D; printf("Call Name through 2d base pointer:%s\n", p2D->Name());
getchar(); }
//Debug下的汇编
00007ff6`20d810d4 488b052d2f0000 mov rax,qword ptr [InsideCPPML!__security_cookie (00007ff6`20d84008)] 00007ff6`20d810db 4833c4 xor rax,rsp 00007ff6`20d810de 4889442450 mov qword ptr [rsp+50h],rax
00007ff6`20d810e3 488d058e110000 lea rax,[InsideCPPML!Point3D::`vbtable' (00007ff6`20d82278)] 00007ff6`20d810ea c744244803000000 mov dword ptr [rsp+48h],3 00007ff6`20d810f2 4889442428 mov qword ptr [rsp+28h],rax 00007ff6`20d810f7 488d4c2440 lea rcx,[rsp+40h]
00007ff6`20d810fc 488d056d110000 lea rax,[InsideCPPML!Point3D::`vftable' (00007ff6`20d82270)] 00007ff6`20d81103 c744244c04000000 mov dword ptr [rsp+4Ch],4 00007ff6`20d8110b 4889442420 mov qword ptr [rsp+20h],rax
00007ff6`20d81110 488d0541110000 lea rax,[InsideCPPML!Point3D::`vftable' (00007ff6`20d82258)] 00007ff6`20d81117 4889442440 mov qword ptr [rsp+40h],rax 00007ff6`20d8111c c744243c00000000 mov dword ptr [rsp+3Ch],0 00007ff6`20d81124 c744243005000000 mov dword ptr [rsp+30h],5
//call get name
//virtual function getname 00007ff6`20d8112c ff152e110000 call qword ptr [InsideCPPML!Point3D::`vftable'+0x8 (00007ff6`20d82260)]
//printf first parameter 00007ff6`20d81132 488bd0 mov rdx,rax
//printf second parameter:"Call Name through 2d base pointer:%s\n"
00007ff6`20d81135 488d0dec100000 lea rcx,[InsideCPPML!`string' (00007ff6`20d82228)]
// call printf
00007ff6`20d8113c e8cffeffff call InsideCPPML!printf (00007ff6`20d81010)
00007ff6`20d81141 ff1521100000 call qword ptr [InsideCPPML!_imp_getchar (00007ff6`20d82168)]
00007ff6`20d81147 33c0 xor eax,eax
00007ff6`20d81149 488b4c2450 mov rcx,qword ptr [rsp+50h]
00007ff6`20d8114e 4833cc xor rcx,rsp
00007ff6`20d81151 e82a000000 call InsideCPPML!__security_check_cookie (00007ff6`20d81180)
00007ff6`20d81156 4883c468 add rsp,68h
00007ff6`20d8115a c3 ret
00007ff6`20d8115b cc int 3
10、C++程序设计模型支持三种programming paradigms(程序设计范式):程序模型(procedural model); 抽象数据类型模型(abstract data type model);面向对象模型(object-oriented model);
11、多重继承的数据布局:

12、在你开始“程序代码层面的优化操作”以加速程序运行之前,你应先确实的测试效率,而不是靠推论和常识进行判断。虚拟继承效率令人失望,但虚拟继承和菱形继承的关系是什么呢?
13、

14、NRV(named return value) 是编译器对返回值实现的一种优化,如果返回一个临时对象,如果没有NRV,会多一层拷贝操作,NRV避免了这一点。
15、Inline函数可以有效存取class中的nopublic数据,同时也是C程序当中#define的替代品(特别是宏当中有参数副作用的话)。缺点:如果inline被调用太多次的话,会产生大量的扩展码,使程序大小暴涨。
16、虚继承对象如何析构:

17、一个编译器必须保持两个scope contexts: 1."scope of template declaration",用于专注于一般的template class; 2、”scope of the template instantiation",用于专注于特定的实例,编译器的决议(resolution)算法必须决定哪一个才是适当的scope,然后在其中搜寻适当的name.
18、单一继承和多重继承的内存布局:


参考文献:
1、https://blog.csdn.net/u011569253/article/details/80950293
汇编当中的ILT: import lookup table.
浙公网安备 33010602011771号