Item 43: Know how to ... 比如父类模板中的名称对子类模板不是直接可见的需要通过this->前缀、using或显式地特化模板父类来访问父类中的名称。 因为父类模板在实例化之前其中的名称是否存在确实是鈈确定的而
按照通常的习惯我们这样设计┅个类或者结构(体):
这是一个很好的习惯,至少我是这么认为的
不愉快的事情时有发生
如果坚持这个套路,我们编写一个模板比如模板函数、模板类,哐当在一个实际
应用中,出现了如下链接(LINK)错误:
这是一个用于的简化示例具体代码结构如下
在MyTemplate中定义了一个testFunc模板函數,然后在主函数中调用了一个特化实例
分析以上代码你可能会说:“没问题呀,怎么会出现链接错误呢”
问题的根源在于编译器对於模板(template)的编译处理过程中,
大致是这样的(果真如此么):
1、模板函数testFunc在编译(compile)期间并未生成具体二进制代码,
在main函数中也没有嵌入这个函数嘚代码可能只是包含了一句
2、编译阶段,在main函数中发现了testFunc的引用但是main.obj中没有相关的
可执行代码(编译器认为该函数在别处定义,这就昰为什么需要链接也就是
3、链接阶段将各个模块(编译期间生成的很多*.obj文件)组织起来
在main中从调用处jump到这里即可,执行完毕再跳出子模块從“中断点”
4、模板在编译期间是不生成具体代码的,除非有特化的引用比如上述的
文件中,然后主函数中引用到testFunc的一个特化实例因為MyTemplate和Main
(根据你编译器的设置可能会有不同,这是按照默认设置生成的中间文件名称)
在编译MyTemplate的过程中没有找到任何特化实例(头文件为模板聲明,
源文件亦为模板实现)因此不生成任何可执行实例代码
因此只是给出了call testFunc的“字样”而不是具体执行代码,就是说寄希望于
链接阶段在别的模块中找到testFunc的定义
于是在LINK阶段需要查找testFunc的实现定义,不幸的是找不到了,于是出现
那么如何解决这个问题呢?
1、在一个文件中完成模板的声明及实现
第二种方式还不如第一种方式简洁实际上就是一个东西,
第三种方法可能会造成而外开销(比如多个模块都調用了这个模板的某个特化实例的
但一般来说这种开销不算什么除非你的要求很严格,那么请采用第一种方式吧
采用第三种方法进行测試
启动调试然后打开反汇编窗口(VS2013下的默认快捷键是 Ctrl+Alt+D)
注意红色方框标注的那一行
如此便验证了本文开头的解释
事实上除了模板,抽象類等也不能被实例化在这种情况下,建议采用上述的
在一个文件中完成模板的声明及实现
版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。