Nisy 发表于 2010-1-19 01:06:13

关于那个传说中的虚表(浅析构造顺序)

1.
this 指针是通过寄存器传参过去的

2. 类的 构造 和 析构 时都会对虚表进行赋值 (虚表在编译的时候就已经写入代码段了)
即对
mov ,ecx
mov ecx,
mov ,offset class::`vftable' (虚表的地址)

所以通过 构造和析构函数 都是可以找到该类的虚表的

3. 关于大忽悠虚表

class People
{
virtual ~People()
}

class Student: public People
{}

int main(int argc, char* argv[])
{
        Student stu(1,2,3);
        Student * pstu = new Student(1,2,3);
        delete pstu;
        return 0;
}

Student 的虚表中成员 仅仅为 父类的虚表集,子类的虚函数要进去想都别想 ~ 这个大家都知道哈
也就是说子类单独定义的虚表想进入多态 想都别想哈 ~~

虚表的顺序 就是 父类中虚表定义的书序哈 跟子类如何定义无关~~

而对象的虚表中 虚函数 自身在虚表吗? 答案是 No 而是另一个间接调用虚函数的函数填充了所谓的虚函数
(就是这个东西啦哈 scalar deleting destructor)

上边代码即可测试 这里点到为止好了 ~~

Nisy 发表于 2010-1-19 10:37:35

拷贝构造中初始化类表的顺序

1. 先看一下Copy构造

public:
        char * m_pName;
        int m_nAge;
        int m_nHeight;

34:
35:   People::People(const People &obj):m_nAge(obj.m_nAge),
36:       m_pName(obj.m_pName),m_nHeight(obj.m_nHeight)
37:   {
00411850   push      ebp
00411851   mov         ebp,esp
00411853   sub         esp,44h
00411856   push      ebx
00411857   push      esi
00411858   push      edi
00411859   push      ecx
0041185A   lea         edi,
0041185D   mov         ecx,11h
00411862   mov         eax,0CCCCCCCCh
00411867   rep stos    dword ptr
00411869   pop         ecx
// 从这里开始 配对COPY ~
0041186A   mov         dword ptr ,ecx
0041186D   mov         eax,dword ptr
00411870   mov         ecx,dword ptr
00411873   mov         edx,dword ptr
00411876   mov         dword ptr ,edx
00411879   mov         eax,dword ptr
0041187C   mov         ecx,dword ptr
0041187F   mov         edx,dword ptr
00411882   mov         dword ptr ,edx
00411885   mov         eax,dword ptr
00411888   mov         ecx,dword ptr
0041188B   mov         edx,dword ptr
0041188E   mov         dword ptr ,edx
00411891   mov         eax,dword ptr
00411894   mov         dword ptr ,offset People::`vftable' (00428038)
38:       // 拷贝构造中只默认添加一个虚表的写入操作
39:       // 先写虚表 再复制
40:   //m_nAge = obj.m_nAge;
41:   //m_nHeight = obj.m_nAge;
42:   //m_pName = obj.m_pName;
43:   }
0041189A   mov         eax,dword ptr
0041189D   pop         edi
0041189E   pop         esi
0041189F   pop         ebx
004118A0   mov         esp,ebp
004118A2   pop         ebp
004118A3   ret         4

2.拷贝构造确实是按老师说的 不管初始化类表如何 都按照类的定义顺序来赋值

People::People(int age,int heigth,char * pName):m_nAge(age),
        m_nHeight(heigth),m_pName(pName)

004013D9   pop         ecx
004013DA   mov         dword ptr ,ecx
004013DD   mov         eax,dword ptr
004013E0   mov         ecx,dword ptr
004013E3   mov         dword ptr ,ecx
004013E6   mov         edx,dword ptr
004013E9   mov         eax,dword ptr
004013EC   mov         dword ptr ,eax
004013EF   mov         ecx,dword ptr
004013F2   mov         edx,dword ptr
004013F5   mov         dword ptr ,edx

besterChen 发表于 2010-1-19 21:18:33

原帖由 Nisy 于 2010-1-19 01:06 发表 https://www.chinapyg.com/images/common/back.gif
2. 类的 构造 和 析构 时都会对虚表进行赋值 (虚表在编译的时候就已经写入代码段了)
即对
mov ,ecx
mov ecx,
mov ,offset class::`vftable' (虚表的地址)

所以通过 构造和析构函数 都是可以找到该类的虚表的

构造就是让this指针指向虚表,所以,知道this指针了,就知道虚表位置了,没有必要再去看构造或者析构……

3. 关于大忽悠虚表
这个没有看懂,等老方讲过多态以后再来看~

2.拷贝构造确实是按老师说的 不管初始化类表如何 都按照类的定义顺序来赋值
这个是为什么不按照初始化类表的顺序来定义来着?
老师讲这个的时候,我睡着了~/:012

[ 本帖最后由 besterChen 于 2010-1-19 21:22 编辑 ]

Nisy 发表于 2010-1-20 11:38:44

原帖由 besterChen 于 2010-1-19 21:18 发表 https://www.chinapyg.com/images/common/back.gif


构造就是让this指针指向虚表,所以,知道this指针了,就知道虚表位置了,没有必要再去看构造或者析构……


这个没有看懂,等老方讲过多态以后再来看~

这个是为什么不按照初始化类表的顺序来定义来着?
...

构造就是让this指针指向虚表
    ==>是填虚表指针 虚表是编译时就弄好的 在数据段 不是指向虚表


为什么不按照初始化类表的顺序来定义来着
    ==>一会告诉你哈

MeowCat 发表于 2010-1-26 22:26:47

打酱油的来抄笔记了。。。。。。看不懂啊 看不懂。/:002
页: [1]
查看完整版本: 关于那个传说中的虚表(浅析构造顺序)