跨dll中使用单例 不要使用模板
来源:互联网 发布:淘宝客服制度 编辑:程序博客网 时间:2024/04/29 18:41
C++中模板单例的跨SO(DLL)问题:RTTI,typeid,static,单例
(转载请注明原创于潘多拉盒子)
C++的模板可以帮助我们编写适合不同类型的模板类,给代码的复用性提供了极大的方便。近来写了一个涉及单例的C++模板类,简化下来可以归结为以下的代码:
1
2
3
4
5
6
7
8
9
10
11
template
<
typename
T>
class
Singleton
{
public
:
// 此处省去了多线程安全锁
static
T* getInstance()
{
static
T t;
return
&t;
}
};
那么如果希望对某个work horse类,比如叫做Foo,定义一个Singleton,就会很容易啦:
1
Foo* foo = Singleton<Foo>::getInstance();
注意这里不需要自己释放foo,因为它不是new出来的。
如果代码被编译成“一个”so(dll)或可执行文件,这里的Singleton得到的对象却是是单例的,也就是说,某一种类型得到的对象地址是确定的。
但是,如果同一个类型的单例在不同的so(dll,可执行文件)中使用,那么得到的同一个类型的单例对象,其地址也是不一样的。比如
libfoo.so文件中的如下代码:
1
2
Foo* foo = Singleton<Foo>::getInstance();
std::type_info fooType =
typeid
(Singleton<Foo>);
和libbar.so中的另一端代码:
1
2
3
Foo* bar = Singleton<Foo>::getInstance();
std::type_info barType =
typeid
(Singleton<Foo>);
其中foo和bar的地址是不同的!他们并不是真正的单例。
为什么呢?原因是模板是编译的时候实例化成“真正的类”的,而在两个不同的so编译生成的过程中,编译器进行了两个不同的实例化过程,他们被实例化成了不同的类。也不是完全不同,但有部分是不同的。
比如,对上述两个so,如果去测试两个Singleton类型是否为同一类型(RTTI):
1
if
(fooType == barType)
那么该测试会返回false。但是,如果测试两个类型的名字是否相等:
1
if
(
strcmp
(fooType.name(), barType.name()) == 0)
该测试则会返回true。
这说明,两个类型虽然type_info不同,但名字却是相同的。
在Google上搜了一下相关的信息,发现这确实是一个难题。因此,用模板来实现单例,是无法跨so的。当然,这里不是真正用模板来实现单例,只是用这个例子来演示模板的RTTI特性。
0 0
- 跨dll中使用单例 不要使用模板
- EXE中使用DLL的模板类
- C++ 使用模板 实现单例模式
- ImageLoader 线程池 单例 使用模板
- C++ 使用模板实现单例模式
- 工厂、单例、模板 一次结合使用
- 关于跨dll的模板单例问题
- 在DLL中使用单例模式输出类成员函数
- 不要在#include中使用".."
- 文件名中不要使用空格
- DLL中使用资源
- DLL中使用对话框
- Dll中使用定时器
- DLL中使用资源
- LabVIEW 中使用dll
- spring中写字符串模板的时候注意不要使用#和$
- boost自带的单例模式不能跨dll使用
- C++单例模板类的实现和使用
- shell脚本中echo显示内容带颜色
- 图解正向代理、反向代理、透明代理
- PHP 10问——PART 4
- 51nod 1068 Bash游戏V3
- vim使用技巧
- 跨dll中使用单例 不要使用模板
- Java并发编程:volatile关键字解析
- POCO C++库学习和分析 -- 通知和事件
- python装饰器 示例1
- 内核链表使用举例
- Hololens入门之手势识别(单击、双击)
- shell获取文件扩展名
- IOS 静态库制作
- 欢迎使用CSDN-markdown编辑器