class HungerSingleton
{
private:
class CGarbo // 用于析构s_pInstance
{
public:
~CGarbo()
{
if(HungerSingleton::s_pInstance)
delete HungerSingleton::s_pInstance;
}
};
static CGarbo Garbo;
static HungerSingleton *s_pInstance;
public:
static HungerSingleton * GetInstance()
{
return s_pInstance;
}
};
下为Singleton.cpp:
HungerSingleton* HungerSingleton::s_pInstance = new HungerSingleton;
测试函数:
void TestSingleton()
{
HungerSingleton *phgl = HungerSingleton::GetInstance();
}
测试环境:VS2013的优化已禁用 (/Od),警告等级 4 (/W4)
因为你的 static CGarbo Garbo;的 CGarbo类里面并没有数据成员,CGarbo是一个空类,所以sizeof(CGarbo)==1; 如果CGarbo的public(为了测试方便)加上一个数据成员char c,另外在HungerSingleton类的GetInstance()加上cout << Garbo.c << "n"; 那么sizeof(CGarbo)还是==1; 但是在我加上char c以后,你的CGarbo有了数据成员,此时执行我给你的新改装类,则会满满的报错,error LINK2001(不解释),因为对于无数据成员的类,编译器会产生于有数据成员的类不同的目标代码,所以加上char c以后,类的目标码不同,而且编译器知道你用了未初始化的Garbo.c,如果你不在外部显示提供初始化,是通不过的。但是你去掉cout << Garbo.c << "n";这句,可以通过,因为编译器在编译的时候发现你自始至终没用过Garbo的.c,故不影响链接,不会报错。
另外补充一句,现在的编译器很智能,即使在10年前,Silicon Graphics的N32和N64编译器已经能自动为所有型别提供适当的type_traits的特化版本,进行STL优化。10年过去了,编译器技术突飞猛进,如果你懂汇编,去调整编译器的优化级别,反复观察汇编码,你就知道编译器给你优化了什么了。(我用的的/Od)
最有给你我改的代码,注释部分你好好看看,如果你去掉cout << Garbo.c << "n";的注释,就会报错。此时你再去掉首位的注释去初始化,问题就OK了。
#include
using std::cout;
class HungerSingleton
{
private:
class CGarbo // 用于析构s_pInstance
{
public:
//CGarbo(char c) :c(c){ }
char c;
~CGarbo()
{
if (HungerSingleton::s_pInstance)
delete HungerSingleton::s_pInstance;
}
};
static CGarbo Garbo;
static HungerSingleton *s_pInstance;
public:
static HungerSingleton* GetInstance()
{
//cout << Garbo.c << "\n";
cout << sizeof(CGarbo) << "\n";
return s_pInstance;
}
};
HungerSingleton* HungerSingleton::s_pInstance = new HungerSingleton;
//HungerSingleton::CGarbo HungerSingleton::Garbo('a');
void TestSingleton()
{
HungerSingleton *phgl = HungerSingleton::GetInstance();
}
int main()
{
TestSingleton();
return 0;
}
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。