关于单例模式的一些思考

qscool1987 2011-12-19 03:51:42

#include <iostream>
using namespace std;
class base
{
public:
int getnum(){return num;}
static base* Instance()
{
if(NULL == pIn)
pIn = new base(10);
return pIn;
}
private:
class RAII
{
public:
~RAII()
{
cout << "resource is distructed" << endl;
if(NULL != base::pIn)
delete base::pIn;
}
};
base(int i):num(i)
{

}
static base *pIn;
int num;
static RAII raii;
};
base* base::pIn = NULL;
base::RAII base::raii = base::RAII();

int main()
{
base *pb = base::Instance();
return 0;
}

这是单例模式的测试代码,内部类RAII是用来释放为单例模式所分配的内存
下面是程序运行时的内存结构图

由此产生了疑问:单例模式的内存有必要去释放吗?也就是说,我有必要去写一个类来管理他吗?看了一些博客和设计模式的书对于这个必要性没有做过讨论。
这确实是一个特殊的类,他只有一个对象,分配在堆上,无论定义多少个指针变量,都是指向同一块内存,也就是同一个对象。
并且他的原始指针是一个静态类型的,也就是和程序的生命期相同,假如在中途给释放了,这个指针就悬空了,并且我到目前也没有找到在运行过程中释放它的方法。这里的RAII内部类我觉得也没什么意义,因为是用一个静态的对象来管理的,只有程序结束的时候才会调用析构函数,然而程序结束的时候本来就会自动回收内存。所以意义不是很大。唉,很迷惑,很伤脑经...
...全文
1012 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
lucky-lucky 2011-12-19
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 qscool1987 的回复:]

引用 2 楼 p569354158 的回复:
我觉得你多虑了
singleton是new出来的,那么你就要显示的delete掉
如果你需要在某个特定的阶段释放掉,那么使用析构函数即可

C/C++ code

public:
~base()
{
delete pIn;
pIn = NULL;
}
//在某些时候你,你发现内存太大了,而这个时候这个singleton已经不……
[/Quote]

试了一下,果真不行,经常不编都忘掉了,那只能照一楼的做法来了,但是觉得3楼那不叫singleton,那叫factory
wesleyluo 2011-12-19
  • 打赏
  • 举报
回复
单例本来就是用来获取同一个对象的吧,每次都是获取的同一个对象;
如果你需要多次获取了对象后又释放;就不需要单例,普通对象就可以了;

如果不delete掉单例的内存,那不就内存泄漏了?

qscool1987 2011-12-19
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 ma100 的回复:]
内存泄漏也会有
比如base里面定义了成员变量
struct
{
int *abc
}
那delete base时, abc不会自动释放
[/Quote]
这里是一个单例模式,整个程序过程中就只有一个对象,你说的这种情况对于一般的类来说很有必要,但对于单例模式是否有此必要呢
qscool1987 2011-12-19
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 we_sky2008 的回复:]
必要还是有的,否则可能会造成资源泄露(注意不是内存泄露哦)
因为Singleton的构造函数可以(可能)索求广泛的资源如:网络连接、OS互斥体、进程间通信的handles等等
这使必须确保在程序结束时摧毁这个对象

其实避免这个何时以及怎么摧毁这个唯一对象可以这样定义单件模式

C/C++ code

Singleton &Singleton::Instance(void)……
[/Quote]

我觉得你说的很有道理,我也觉得是有必要的,只是我暂时用不上
qscool1987 2011-12-19
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 p569354158 的回复:]
我觉得你多虑了
singleton是new出来的,那么你就要显示的delete掉
如果你需要在某个特定的阶段释放掉,那么使用析构函数即可

C/C++ code

public:
~base()
{
delete pIn;
pIn = NULL;
}
//在某些时候你,你发现内存太大了,而这个时候这个singleton已经不用了,那么这样
base::~b……
[/Quote]
base::~base();
这样调用不行的,这个用法编译不过的
ma100 2011-12-19
  • 打赏
  • 举报
回复
内存泄漏也会有
比如base里面定义了成员变量
struct
{
int *abc
}
那delete base时, abc不会自动释放
qscool1987 2011-12-19
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 wtbike 的回复:]
你这里有 static base* Instance()
也可以有对应的 static base* UnInstance()吧?在UnInstance里边不就可以释放了?
不过,我仔细翻了下自己维护的这些代码,貌似真的都没有delete
[/Quote]
这个办法不错,我的思维局限在了析构函数里了
这里通过一个函数来显示的释放,可以做到随时释放内存,可不能回答有没释放必要的问题啊
we_sky2008 2011-12-19
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 we_sky2008 的回复:]
必要还是有的,否则可能会造成资源泄露(注意不是内存泄露哦)
因为Singleton的构造函数可以(可能)索求广泛的资源如:网络连接、OS互斥体、进程间通信的handles等等
这使必须确保在程序结束时摧毁这个对象

其实避免这个何时以及怎么摧毁这个唯一对象可以这样定义单件模式

C/C++ code


Singleton &Singleton::Instance(voi……
[/Quote]
详见《C++设计新思维》
we_sky2008 2011-12-19
  • 打赏
  • 举报
回复
必要还是有的,否则可能会造成资源泄露(注意不是内存泄露哦)
因为Singleton的构造函数可以(可能)索求广泛的资源如:网络连接、OS互斥体、进程间通信的handles等等
这使必须确保在程序结束时摧毁这个对象

其实避免这个何时以及怎么摧毁这个唯一对象可以这样定义单件模式

Singleton &Singleton::Instance(void)
{
Singleton only;
return only;
}

lucky-lucky 2011-12-19
  • 打赏
  • 举报
回复
我觉得你多虑了
singleton是new出来的,那么你就要显示的delete掉
如果你需要在某个特定的阶段释放掉,那么使用析构函数即可

public:
~base()
{
delete pIn;
pIn = NULL;
}
//在某些时候你,你发现内存太大了,而这个时候这个singleton已经不用了,那么这样
base::~base();//现在释放掉了,而后面你发现又要使用这个singleton了,同样再来返回个实例
base *pb = base::Instance();//又可以使用了
//又不想用了
base::~base();
//又需要了
base *pb = base::Instance();
.........

这种方法在多线程还需要改一改,考虑的问题较多
wtbike 2011-12-19
  • 打赏
  • 举报
回复
你这里有 static base* Instance()
也可以有对应的 static base* UnInstance()吧?在UnInstance里边不就可以释放了?
不过,我仔细翻了下自己维护的这些代码,貌似真的都没有delete

64,662

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧