2011-01-06 78 views
2

所以,我找到了不同的方法来实现单例的“创建”。
编辑:当我说“创造”,我的意思是。这段代码当然会放在Singleton :: {ctor}或静态Singleton :: Init()函数中。Singleton实现之间的区别

//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; 

它们之间有任何显着差异吗?
据我所知,v2和v3应该是相同的,但它的v1我不是很了解。我知道它做了什么,但是为了什么目的?

另外,请不要把它变成“Singletons are BAAAAD”的讨论。

+3

WTH是吗?看起来像参加这个比赛:www.ioccc.org/main.html – 2011-01-06 08:31:37

+1

um。你可以通过静态指针指向类来创建一个单例,然后创建一个静态工厂函数来创建这个类,或者返回现有的指针。我不知道这段代码在做什么,除了很多不必要和危险的演员。 – 2011-01-06 08:32:16

+0

@Xeo nice gravatar – abel 2011-01-06 08:36:34

回答

2

(因为这个问题似乎已经死了,我会尽力回答对我自己。)
什么v1所做的是手动调节this指针指向派生类对象的地址。通常,static_cast或普通的c风格转换本身就是这样做的,但在早期的编译器中可能并非如此,或者存在错误。以往的情况是,它会演员扮演什么角色。

1

v2和v3几乎相同,但v3使用的是C风格的转换(C++风格的转换更安全,因为在编译时会得到更多的检查)。

V1是...哇...以下是它在做什么:

  • 投数1Ty类型的指针,并返回到int。我预计这仍然会产生1
  • 将数字1转换为我的类型Ty的指针,将其转换为指针cSingleton<Ty>,最后返回int。我预计这仍然是1
  • 减去两者。我希望它可以为0。
  • 在v2和v3设置单到this一样,但调整为“偏移”

我猜有某处建筑的一些怪癖,其中的结果铸造1会导致您获得非1结果,所以偏移量将不为零。因此,这将是一种调整平台上的怪癖的方法。

这是一个猜测,但我希望会有一些意见来解释代码(但可能不会)。也许有人可以用比我更具体的答案作为参考,但希望这可以让你继续下去。

0

Here是一个不错的单例C++示例。我不知道你为什么使用这种编码,这不是好的做法。