内容简介:C++中的单例
写C++的时候用到单例,于是很自然的写出如下的代码:
namespace tlanyan {
class Foo {
private:
static Foo* _instance;
Foo() {}
// other members
public:
static Foo* getInstance() {
if (_instance == NULL) {
_instance = new Foo();
}
return _instance;
}
~Foo() {
// clean codes
}
// other members and codes
};
Foo* Foo::_instance = NULL;
}
代码的本意:静态成员函数getInstance获取单例指针,并且在析构函数中做一些收尾工作。
运行代码后发现析构函数死活不执行,难道一个单例模式都能写错?反复确认,没发现问题所在,于是上万能的StackOverflow上找原因。正好有伙计有同样的疑惑,有哥们给出了一个 可行的方案 。根据其答案修改代码如下:
namespace tlanyan {
class Foo {
private:
Foo() {}
// other members
public:
static Foo& getInstance() {
static Foo _instance;
return _instance;
}
~Foo() {
// clean codes
}
// other members and codes
};
}
对比前一段代码,主要改动是移除了静态指针成员,改用函数内的静态成员。由于_instance是函数内的静态成员,在首次调用时被初始化(感谢无参构造函数),之后调用将略过初始化而执行后续代码;函数返回实例的引用,故而每次调用得到的是同一个对象,达到了单例的目的;程序执行结束后,实例的析构函数被自动调用,析构函数中的代码正确执行。
问题解决了,但什么原因造成第一段单例代码的析构函数不执行呢?
这是由于C++持有对象的方式造成的(或者说C++允许 程序员 手动控制内存引起)。Java/PHP等带有回收机制的语言,持有对象的方式是通过指针,程序员申请对象后会自动分配内存,系统负责跟踪和回收无用的对象和存在。C++允许开发人员以变量的方式持有对象,例如: Foo foo [= Foo(args)]
。变量初始化后获得对象的引用,离开作用域后,系统销毁执行栈,对象自动被析构。C++也可以以指针的形式获得对象的引用: Foo* foo = new Foo(args)
。这种方式分配的对象,需要开发人员手动管理。如果不执行delete,对象和分配的内存将一直存在,直到程序退出后,才由操作系统回收。如下代码可说明这点:
namespace tlanyan {
void foo() {
Foo foo; // 声明变量,编译器会自动初始化变量
Foo* ptr = new Foo(); // 声明对象指针,同时为对象开辟内存
// awesome codes
return; // 离开作用域, foo对象将被自动析构;如果之前没有调用过delete ptr, ptr指向的对象将一直存在;如果delete ptr,析构函数将被执行。也可以将ptr指向的对象赋值给外层作用域的指针,此时有多个指针指向同一个变量
}
}
从上面的代码可以看出,对象没有引用计数的情况下,编译器和系统不敢随便回收new出来的对象内存:多个指针指向同一个对象,delete了对象可能会导致其他代码崩溃;释放内存后,其他指针再delete会多次delete同一块内存,引发不可预知风险。
综上,指针单例析构函数没有被调用的原因是: 自己new的对象,需要自己delete,别指望别人帮你正确调用析构函数。
问题的解决方案有以下几种:
- 同StackOverflow上回答,改用变量方式持有单例对象。程序运行结束前会销毁所有变量,变量的析构函数将被正确调用;
- 在main函数退出前delete单例。例如增加一个destroy的静态成员函数,将指针指向的对象销毁;
- 使用auto_ptr/unique_ptr等智能指针。
如有其它解决方案,欢迎交流指正!
参考
- https://stackoverflow.com/questions/6993400/managing-a-singleton-destructor
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Build Your Own Web Site the Right Way Using HTML & CSS
Ian Lloyd / SitePoint / 2006-05-02 / USD 29.95
Build Your Own Website The Right Way Using HTML & CSS teaches web development from scratch, without assuming any previous knowledge of HTML, CSS or web development techniques. This book introduces you......一起来看看 《Build Your Own Web Site the Right Way Using HTML & CSS》 这本书的介绍吧!