| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 683 人关注过本帖
标题:请教大家一个关于Singleton的问题
只看楼主 加入收藏
yuki
Rank: 2
等 级:新手上路
威 望:5
帖 子:508
专家分:0
注 册:2005-2-4
收藏
 问题点数:0 回复次数:5 
请教大家一个关于Singleton的问题
请看一段代码
程序代码:
#include "stdafx.h"
#include <stdio.h>
#include <windows.h>

class Singleton
{
protected:
    Singleton() {}
private:
    Singleton(const Singleton&) {}
    Singleton& operator=(const Singleton&) { return *this; }
    ~Singleton() {}
public:
    inline static Singleton *getInstance()
    {
        return m_pInstance;
    }
private:
    static Singleton *m_pInstance;
};

Singleton *Singleton::m_pInstance = new Singleton;

class CriSec : public Singleton
{
protected:
    CriSec() {}
public:
    void init() { InitializeCriticalSection(&m_objCriSec); }
    void lock() { EnterCriticalSection(&m_objCriSec); }
    void unlock() { LeaveCriticalSection(&m_objCriSec); }
    void release() { DeleteCriticalSection(&m_objCriSec); }
private:
    CRITICAL_SECTION m_objCriSec;
};

class Foo : public Singleton
{
protected: 
    Foo() {}
public:
    void foo() { printf("Hello,world!\n"); }
};

int main(int argc, char* argv[])
{
    Foo *pObj1 = (Foo *)Foo::getInstance();
    CriSec *pObj2 = (CriSec *)CriSec::getInstance();

    pObj2->init();
    pObj2->lock();
        pObj1->foo();
    pObj2->unlock();
    pObj2->release();

    return 0;
}

这段代码主要实现了三个类,第一个为Singleton(单态,也就是说所有继承Singleton类的派生类只允许拥有唯一的一个实例),两外CriSec和Foo类都是继承Singleton的单态类,CriSec主要实现了临界区变量使用的封装,Foo类只是用来测试的。
问题是:
1、
对于Singleton中的静态成员初始化时直接new Singleton后通过getInstance()将m_pInstance返回给客户,这里存在一个问题,举个例子:
有类A,类B,其中类B继承类A,则
A *p = new B;
B *p1 = (B *)p; // 安全

A *p = new A;
B *p1 = (B *)p; // 不安全,B没有实例化,只能使用A提供的方法
那么这里问题来了,m_pInstance紧紧使之实例化为Singleton,而并没有实例化为Foo或CriSec类,为能安全的是用这两个类所提供的方法,从watch窗口可以看到,无论是Foo::getInstance()还是CriSec::getInstance()返回的都是同一个指针,却能安全使用这两个没有实例化的类感到很疑惑;若对于2个从Singleton派生的类能够正常工作,那么对于大于2个从Singleton派生的类,是否会造成不可预料的情况?
2、
其中静态成员m_pInstance一旦初始化后,即new了个指针出来,就没有办法删除了,原因之一是m_pInstance是个私有成员,第二个就是Singleton将析构私有化了,然而,通过实验,把m_pInstance和~Singleton()都置为public可以顺利通过编译,在程序最后加上delete m_pInstance;却发生断言,难道m_pInstance已经销毁类(不可能吧),还是static变量系统会自动清理?

程序能正常运行,希望大家给予帮助,谢谢。
搜索更多相关主题的帖子: Singleton 
2008-04-05 20:38
aipb2007
Rank: 8Rank: 8
来 自:CQU
等 级:贵宾
威 望:40
帖 子:2879
专家分:7
注 册:2007-3-18
收藏
得分:0 
1:确实会造成错误,如果你在Foo类中加上int *p成员,构造函数中new int(0),再输出*p看看,肯定错,因为Foo没有实例。
2:可以直接delete的(无论是delete pObj1还是pInstance),我没出现你说的错误。

ps:你用的什么编译器?你上面的代码把基类析构设置private,派生类中调用会出错的。

Fight  to win  or  die...
2008-04-06 00:49
yuki
Rank: 2
等 级:新手上路
威 望:5
帖 子:508
专家分:0
注 册:2005-2-4
收藏
得分:0 
我尝试了一下,有指针的情况的确会发生问题,我用的是VC6.0,对于私有析构调用并没有错误。
请问有没有什么更好的方法实现Singleton,我的项目中有多个类需要单态化,谢谢。

我们都在命运湖上荡舟划桨,波浪起伏使我们无法逃离孤行;如果我们迷失方向,波浪将指引我们穿过另一天曙光
2008-04-06 08:10
aipb2007
Rank: 8Rank: 8
来 自:CQU
等 级:贵宾
威 望:40
帖 子:2879
专家分:7
注 册:2007-3-18
收藏
得分:0 
惭愧,我也不知道更好的办法,几乎都是用静态变量这样做。
你搜索下网络或者问问其他人吧!

o(∩_∩)o...

Fight  to win  or  die...
2008-04-06 10:23
sunkaidong
Rank: 4
来 自:南京师范大学
等 级:贵宾
威 望:12
帖 子:4496
专家分:141
注 册:2006-12-28
收藏
得分:0 
涉及类的上行和下行问题..我也不明白.为什么指向基类的指针怎么能访问派生类没有实例的对象的...而且即使实例了...又没虚函数怎么实现多态的...隐藏的概念呢?..怎么弄的和java似得?还有Singleton *Singleton::m_pInstance = new Singleton;Singleton构造函数是私有为什么这里可以用呢?

[[it] 本帖最后由 sunkaidong 于 2008-4-6 11:55 编辑 [/it]]

学习需要安静。。海盗要重新来过。。
2008-04-06 11:12
yuki
Rank: 2
等 级:新手上路
威 望:5
帖 子:508
专家分:0
注 册:2005-2-4
收藏
得分:0 
不管怎么样,谢谢两位关注,我再想想其它方法。

sunkaidong提到了java,的确java的许多库都是给予设计模式的思想设计的,无论从代码的扩展性和可维护性来说都是相当优秀的,其中Singleton模式用的也比较多的,两外MFC中有些对象不能直接使用,而需要通过getInstance来获得实例后才能使用,这种方法就是给予Singleton的模式设计的;从总体上来说MFC用了相当多的设计模式,其中视图和文档的概念,文档管理多个视图,也就是把每个视图作为观察对象交给文档管理,通过调用Invalidate()(好像是这个函数)来通知视图的更新,这样所有的视图需要更新时,只需调用update();

设计模式好是很好,但自己用起来比较吃力,好吧我再想想办法,再次感谢各位。

我们都在命运湖上荡舟划桨,波浪起伏使我们无法逃离孤行;如果我们迷失方向,波浪将指引我们穿过另一天曙光
2008-04-06 16:41
快速回复:请教大家一个关于Singleton的问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.017811 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved