用汇编的眼光看C++(之模板类) (二)

2014-11-24 12:43:50 · 作者: · 浏览: 1
66666666h

0040129A push 3FF33333h

0040129F push 33333333h

004012A4 lea ecx,[ebp-28h]

004012A7 call @ILT+60(data_process::data_process) (00401041)

004012AC mov byte ptr [ebp-4],2

63: int i_d = d.add();

004012B0 lea ecx,[ebp-14h]

004012B3 call @ILT+70(data_process::add) (0040104b)

004012B8 mov dword ptr [ebp-2Ch],eax

64: char c_m = m.add();

004012BB lea ecx,[ebp-18h]

004012BE call @ILT+80(data_process::add) (00401055)

004012C3 mov byte ptr [ebp-30h],al

65: double d_p = p.add();

004012C6 lea ecx,[ebp-28h]

004012C9 call @ILT+75(data_process::add) (00401050)

004012CE fstp qword ptr [ebp-38h]

66:

67: }

60: data_process d(1,2);

0040126D push 2

0040126F push 1

00401271 lea ecx,[ebp-14h]

00401274 call @ILT+45(data_process::data_process) (00401032)

00401279 mov dword ptr [ebp-4],0

61: data_process m('1', '2');

00401280 push 32h

00401282 push 31h

00401284 lea ecx,[ebp-18h]

00401287 call @ILT+55(data_process::data_process) (0040103c)

0040128C mov byte ptr [ebp-4],1

62: data_process p(1.2, 2.3);

00401290 push 40026666h

00401295 push 66666666h

0040129A push 3FF33333h

0040129F push 33333333h

004012A4 lea ecx,[ebp-28h]

004012A7 call @ILT+60(data_process::data_process) (00401041)

004012AC mov byte ptr [ebp-4],2

63: int i_d = d.add();

004012B0 lea ecx,[ebp-14h]

004012B3 call @ILT+70(data_process::add) (0040104b)

004012B8 mov dword ptr [ebp-2Ch],eax

64: char c_m = m.add();

004012BB lea ecx,[ebp-18h]

004012BE call @ILT+80(data_process::add) (00401055)

004012C3 mov byte ptr [ebp-30h],al

65: double d_p = p.add();

004012C6 lea ecx,[ebp-28h]

004012C9 call @ILT+75(data_process::add) (00401050)

004012CE fstp qword ptr [ebp-38h]

66:

67: }

上面的代码有点长,我们大家来一起看一下:

60句: 定义int型的class类型,可以看到data_process构造函数地址是0x401032

61句: 定义char型的class类型,看到data_process构造函数地址是0x40103c

62句:定义double型的class类型,看到data_process构造函数地址是0x401041

63句:调用data_process的add成员函数,地址为0x40104b

64句:调用data_process的add成员函数,地址为0x401055

65句:调用data_process的add成员函数,地址为0x401050

上面的代码表明,其实编译器为我们函数中出现的每一个具体类实例化了一遍。针对每一个类型,模板的构造函数、析构函数、成员函数都要独立生成,这从上面的函数地址就可以看出来,没有什么神奇的。所以,我们明白了模板的本质就是对不同数据类型的相似性操作进行共同属性提取,合成模板。在应用的时候,编译器根据我们使用中的数据类型独立生成每一个类,构建每一个基本运算变量和运算函数,仅此而已。

模板注意事项:

(1)class上出现的问题在模板类上都会出现

(2)先把class写好,然后再转变成模板类

(3)如果不是数据类型的差异,而是共有数据数量上的差异,请选用继承代替模板

(4)模板中的type可以是自定义类型

(5)模板代码只能出现在头文件中,出现在*.cpp文件中没有意义,单独的*.cpp模板代码因为没有涉及具体类型,因此不会编译成任何二进制代码

(6)不同版本的vc对模板支持有差异,编译错误不一定是你自己的原因,但是绝大部分应该是你的原因

(7)模板生成的告警很冗长,一个warning或者是error 30~50行很正常,不要害怕,孰能生巧