C++ 单例实现之间的差异

C++ 单例实现之间的差异,c++,singleton,C++,Singleton,因此,我找到了不同的方法来实现单例的“创建”。 编辑:当我说“创造”时,我是认真的。当然,这段代码将放在Singleton::{ctor}或静态Singleton::Init()函数中 //v1 //the first "1" is casted to a pointer to Ty, then that pointer is casted //back to int to obtain the hex address //the second 1

因此,我找到了不同的方法来实现单例的“创建”。
编辑:当我说“创造”时,我是认真的。当然,这段代码将放在Singleton::{ctor}或静态Singleton::Init()函数中

//v1
        //the first "1" is casted to a pointer to Ty, then that pointer is casted
        //back to int to obtain the hex address
        //the second 1 is casted to a pointer to Ty, then to a pointer
        //to cSingleton<Ty> because Ty is a derived class and finally
        //back to int to get the hex address
        //after that it's simple pointer arithmetics to get the offset
        int offset = (int)(Ty*)1 - (int)(cSingleton <Ty>*)(Ty*)1;
        m_pSingleton = (Ty*)((int)this + offset);
//v2
        m_pSingleton = static_cast<Ty*>(this);
//v3
        m_pSingleton = (Ty*)this;
//v1
//第一个“1”被强制转换为指向Ty的指针,然后该指针被强制转换
//返回int以获取十六进制地址
//第二个1被转换为指向Ty的指针,然后转换为指向Ty的指针
//因为Ty是一个派生类
//返回int以获取十六进制地址
//然后,用简单的指针算法得到偏移量
整数偏移量=(整数)(Ty*)1-(整数)(cSingleton*)(Ty*)1;
m_pSingleton=(Ty*)((int)此+偏移量);
//v2
m_pSingleton=静态施法(本);
//v3
m_pSingleton=(Ty*)本;
它们之间有显著差异吗?
据我所知,v2和v3应该是相同的,但我不太理解v1。我知道它是干什么的,但目的是什么


另外,请不要把这变成“单例是baaad”的讨论。

v2和v3基本相同,但v3使用的是c风格的强制转换(c++风格的强制转换更安全,因为在编译时会得到更多的检查)

v1是。。。哇!下面是它正在做的事情:

  • 将数字
    1
    投射到我类型的指针
    Ty
    ,然后返回到
    int
    。我希望这仍然会产生
    1
  • 将数字
    1
    转换为我类型的指针
    Ty
    ,将其转换为
    cSingleton
    ,最后返回到
    int
    。我希望这仍然是
    1
  • 减去两者。我希望这是0
  • 将单例设置为
    ,如v2和v3中所示,但调整“偏移量”
我猜在某个地方,架构中有一些怪癖,在那里,强制1的结果会导致一个非1的结果,所以偏移量会是非零的。因此,这将是一种在平台上调整铸造怪癖的方法

这只是一个猜测,我希望会有一些注释来解释代码(但可能不会)。也许有人能比我更具体地回答,但希望这能给你一些继续下去的东西。

是一个很好的单例C++例子。我不知道您为什么要使用这种编码,这几乎不是一种好的做法。

(因为这个问题似乎已经解决了,我将试着自己回答它。)

v1
所做的是手动调整
this
指针以指向派生对象的地址。通常情况下,
static\u cast
或普通的c风格cast本身就可以做到这一点,但早期的编译器可能不是这样,或者存在错误。不管是什么情况,它都会像演员那样做。

?看起来像是本次比赛的参赛作品:www.ioccc.org/main.htmlum。通过使用指向该类的静态指针,然后使用创建该类或返回现有指针的静态工厂函数,可以“创建”一个单例。我不知道这段代码在做什么,除了许多不必要的和危险的强制转换。Singleton应该有私有构造函数,这意味着在创建Singleton实例之前不能有
这个
指针。如果你已经有了一个实例(你的单身汉),那么上面的代码在做什么?@abel:为什么谢谢你。:)@纳瓦兹:就像我编辑的一样,这只是ctor的一个片段,或者静态初始化函数V1在技术上是不合法的代码。不能将任意值强制转换为指针。理论上,有些机器(我相信有些仍然存在)有特殊的指针寄存器,如果在其中放置了无效地址,这些寄存器就会出错。这只是一个例子,有不同的方法来处理不同的场景,比如多线程…IIRC,singleton有时会出错。在该示例中,无论
pinstance
的值如何,都需要使用new来创建新实例。一旦您有了新的
*pinstance
,使用您平台的(原子)CMPEExchange指令或编译器内部来测试零,如果零,则替换为新的
pinstance
。如果不更换
pinstance
,请将其删除。Alexandrescu有一篇关于这个主题的论文,但我不记得名字,也找不到。