跨dll中使用单例 不要使用模板

转载 2016年08月31日 16:10:43

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特性。

相关文章推荐

boost自带的单例模式不能跨dll使用

1.问题描述使用qt自带的model/view实现,在dll中对model进行赋值,在exe中使用model在view中显示,基于boost自带的singleton实现时出现了赋值后显示为空数据的错误...

c++ dll 单例模式出现多个单例对象

源url: http://www.cnblogs.com/bourneli/archive/2011/12/28/2305280.html 我这里的问题主要是这样的: 有三个project, Proj...

dll 中定义的单例类如何让外部使用

这两天因为一个单例类要定义在dll中,而对外部要b

读取/写入位置发生访问冲突

问题描述 C/C++程序运行时提示读取/写入位置发生访问冲突。例如:0x00007FFF33515D43 (swscale-4.dll) (QTDemo0.exe 中)处的第一机会异常:  0xC0...
  • gkzscs
  • gkzscs
  • 2016年06月08日 15:41
  • 2468

0x669586df (QtCored4.dll) 处最可能的异常: 0xC0000005: 写入位置 0xabababab 时发生访问冲突

0x669586df (QtCored4.dll) 处最可能的异常: 0xC0000005: 写入位置 0xabababab 时发生访问冲突         pSubWnd = ne...

工厂、单例、模板 一次结合使用

工厂: Java代码   /**   * 创建各个 单例csvReader的工厂   * @author wj   * @date 2017-1-7   *   ...

单例的使用--弹出框

  • 2017年07月21日 13:14
  • 4KB
  • 下载

Tablayout 单例和混合使用

  • 2016年03月02日 17:42
  • 11.1MB
  • 下载

c# 使用Interop.Excel.dll官方组件导出Excel(根据模板)

此方法先保存至服务器,再从服务器端进行下载,当数据量比较大的时速度比较慢 在开发的当前项目中引入:Microsoft.Office.Interop.Excel;System.Reflection;命...
  • zr_wb
  • zr_wb
  • 2016年09月21日 17:35
  • 155
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:跨dll中使用单例 不要使用模板
举报原因:
原因补充:

(最多只允许输入30个字)