由类模版中static成员变量的定义引发的思考。。。

说到这个问题还要从一个项目说起,项目中整个系统的日志部分是通过单例模式进行管理的,在设计单例模式的时候,单例类的定义是定义成模版类,且为了实现每个单例类只能有一个实例,实例化返回的对象设计成静态成员变量,如下图Fig 1所示。

 Fig 1.单例模式的定义

由于代码正常习惯,类的定义和实现是分开的,分别在.h.cpp文件中,所以在设计的时候也是分开的,后来就悲剧了,编译的时候怎么都是出现未定义错误。然后我就把定义和实现都放在一起在.h头文件中,然后就OK了,当时真是百思不得其解,但也没有考虑到是模板类的特殊性,后来由于项目很急,也就放在那里,反正也没有什么问题。可以一直拖到现在。(这个坏习惯应该受到强烈鄙视!!!!)

1.模版编译模型

现在回头看,我首先想到的原因就是模板类的问题,后来查了一些资料,终于有了结果。

一般而言,当调用函数时,编译器只需要看到函数的声明就可,定义类的对象时,只需要类的定义就可,成员函数的定义不是必须存在的,因此可以将类的定义和类的实现,函数的声明和函数的定义分别分开存放到.h.cpp文件中。

但模版则不同,要进行实例化,编译器必须要能够访问定义模版的源代码。当调用函数模版或类模版的成员函数时,编译器需要知道函数的定义,需要那些通常放在源文件中的代码。

所以一般情况下,关于模版类和模版函数的定义和实现都是存放在同一个头文件中的。

标准C++提供了编译模版代码定义的两种模型:包含模型分别编译模型在这两个编译模型中,构造程序的方式很大程度上和以前的模式是相同的,类的定义和函数的声明放在头文件中,而函数的定义核类成员的定义放在源文件中。而两种模型的不同在于,编译器怎么样使用来自源文件的定义。目前所有编译器都支持第一种模型:包含模型,只有一些编译器支持第二种模型:分别编译模型

(1)包含模型

由于编译器需要看到模版的定义,可以在函数模版声明和类模板定义的头文件中增加一条#include “source.cpp”语句,指示函数模版的定义和类模版成员的定义。

Fig 2 包含模型的实现

(2)分别编译模型

在此模型中,要让编译器知道给定模版的定义,要用到关键字exportexport关键字能够指明给定的定义可能会需要在其他文件中产生实例化。

  • 对于函数模版,在定义的时候指明函数模版为导出的,即通过在关键字template之前加上关键字export,而函数模版声明的头文件中不需要加export关键字。

Fig 3 分别编译模型之模版函数


  • 而对于类模板,使用export更复杂一些,但和函数模版差不多,export关键字应该用在类模板的实现文件中(源文件),而不应该使用在类模板定义的头文件中。

Fig 4 分别编译模型之模版类

2.static成员变量的定义

类模版中static成员变量的定义和成员函数在模版类外定义一样,都需要加template,如下图Fig 5,是Fig 1中的CSingleton类中的静态成员变量的定义。


Fig 5 static成员变量的定义

但现在有一个问题就是如果把static成员变量的定义放在头文件中,或通过包含模型的方式,都会可能导致静态成员变量的重复定义呀。??????????





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值