C++实现单例模式时的销毁问题,在线等~~~

果冻想 2013-11-20 07:49:10
再讲到单例模式的销毁时,在网上看到以下一段话:
我们知道,程序在结束的时候,系统会自动析构所有的全局变量。事实上,系统也会析构所有的类的静态成员变量,就像这些静态成员也是全局变量一样。利用这个特征,我们可以在C++单例模式类中定义一个这样的静态成员变量,而它的唯一工作就是在析构函数中删除单例类的实例。如下面的代码中的CGarbo类(Garbo意为垃圾工人):

class CSingleton:
{
// 其它成员
public:
static CSingleton * GetInstance(){。。。}
private:
CSingleton(){};
static CSingleton * m_pInstance;
class CGarbo // 它的唯一工作就是在析构函数中删除CSingleton的实例
{
public:
~CGarbo()
{
if (CSingleton::m_pInstance)
delete CSingleton::m_pInstance;
}
};
static CGarbo Garbo; // 定义一个静态成员,在程序结束时,系统会调用它的析构函数
}
类CGarbo被定义为CSingleton的私有内嵌类,以防该类被在其它地方滥用。

在程序运行结束时,系统会调用CSingleton的静态成员Garbo的析构函数,该析构函数会删除单例的唯一实例。

使用这种方法释放单例对象有以下特征:

1.在单例类内部定义专有的嵌套类。

2.在单例类内定义私有的专门用于释放的静态成员。

3.利用程序在结束时析构全局变量的特性,选择最终的释放时机。

4.使用C++单例模式的代码不需要任何操作,不必关心对象的释放。

我就不明白了,这样销毁单例,有什么意义?求指导。
...全文
1582 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
liu_roy 2016-05-16
  • 打赏
  • 举报
回复
http://blog.csdn.net/roy1261/article/details/51425987,这篇里面有详细测试 #include <iostream> using namespace std; class Singleton { public: static Singleton *GetInstance() { if (m_Instance == NULL) { m_Instance = new Singleton(); cout<<"get Singleton instance success"<<endl; } return m_Instance; } private: Singleton(){cout<<"Singleton construction"<<endl;} static Singleton *m_Instance; // This is important class GC // 垃圾回收类 { public: GC() { cout<<"GC construction"<<endl; } ~GC() { cout<<"GC destruction"<<endl; // We can destory all the resouce here, eg:db connector, file handle and so on if (m_Instance != NULL) { delete m_Instance; m_Instance = NULL; cout<<"Singleton destruction"<<endl; system("pause");//不暂停程序会自动退出,看不清输出信息 } } }; static GC gc; //垃圾回收类的静态成员 }; Singleton *Singleton::m_Instance = NULL; Singleton::GC Singleton::gc; //类的静态成员需要类外部初始化 int main(int argc, char *argv[]) { Singleton *singletonObj = Singleton::GetInstance(); return 0; } 我自己参考你的测试了一下,可以析构
tbooka 2014-01-22
  • 打赏
  • 举报
回复
引用 16 楼 vipygd 的回复:
[quote=引用 14 楼 dyw 的回复:] [quote=引用 12 楼 vipygd 的回复:] [quote=引用 10 楼 dyw 的回复:] [quote=引用 6 楼 vipygd 的回复:] [quote=引用 3 楼 dyw 的回复:] [quote=引用 2 楼 vipygd 的回复:] [quote=引用 1 楼 dyw 的回复:] 这样是所谓的RAll机制自动销毁,也可以定义一个静态函数释放单实例指针,但需要你记得调用它。还有的实现方法是在静态函数内定义静态局部对象。
谢谢你的回答,对于所谓的RAll机制自动销毁和在静态函数内定义静态局部对象,有一些不清楚?能否进行说明一下?拜托了。在静态函数内定义静态局部对象是什么机制?[/quote] 1、RAll机制:利用c++的构造与析构特性自动回收资源,智能指针就属于这一类,还有自动关闭句柄等。 2、利用静态局部对象的单例模式:
static A& getInstance()
{
   static A a;
   return a;
}
[/quote] 智能指针,不是使用的引用计数么?这个a貌似没有被释放。我个人认为。如果有不对的地方,请指正,拜托了。[/quote] 有引用计数的智能指针是共享型的,当共享计数为0时自动释放。 a为什么没有被释放?你觉得这个静态对象的析构函数不会被调用吗?为什么? 这里有些讨论:http://stackoverflow.com/questions/1463707/c-singleton-vs-global-static-object[/quote]
/*
#include <iostream>
using namespace std;

class Singleton
{
public:
	static Singleton *GetInstance()
	{
		if (m_Instance == NULL)
		{
			m_Instance = new Singleton();
		}
		return m_Instance;
	}

	int GetTest()
	{
		return m_Test;
	}

private:
	Singleton(){ m_Test = 10; }
	static Singleton *m_Instance;
	int m_Test;

	// This is important
	class GC
	{
	public:
		~GC()
		{
			// We can destory all the resouce here, eg:db connector, file handle and so on
			if (m_Instance != NULL)
			{
				cout<<"Call the GC's destructor"<<endl;
				delete m_Instance;
				m_Instance = NULL;
			}
		}
	};
	static GC gc;
};

Singleton *Singleton::m_Instance = NULL;

int main(int argc, char *argv[])
{
	Singleton *singletonObj = Singleton::GetInstance();
	cout<<singletonObj->GetTest()<<endl;
	
	return 0;
}
谢谢你推荐的文章,但是,这个是个demo,那么cout<<"Call the GC's destructor"<<endl;会执行的,但是实际上,这个语句没有被执行;拜托解释一下。谢谢了。 你推荐的文章中,有人提到以下实现是最好的单例实现:
Printer & thePrinter() {
    static Printer printer;
    return printer;
}
但是,这种单例实现在实际应用中会遇到对象的拷贝问题,你有遇到过吗? 如果修改成以下是否可以:
Printer *thePrinter() {
    static Printer printer;
    return &printer;
}
希望能得到你的指导,谢谢。再次谢谢你耐心的指导。[/quote] 推荐使用只有三行代码的这种实现方式。这种方式在Qt的源码中也很常见。我一般都这样使用。 至于修改为返回指针,同样阻止不了复制行为,想想为什么? 要阻止复制行为,声明拷贝构造函数、赋值函数为私有即可。对于单例模式,由于不允许直接构造,因此构造函数也是私有的。[/quote] 再次感谢你耐心的回答,能给我这么详细的讲解,非常感谢。 对于你的回答,我还是有如下疑问,麻烦你能给我回答一下以下问题,拜托了。 > 至于修改为返回指针,同样阻止不了复制行为,想想为什么?
#include <iostream>
using namespace std;

class Singleton
{
public:
	static Singleton *GetInstance()
	{
		static Singleton m_Instance;
		return &m_Instance;
	}

	/*static Singleton GetInstance()
	{
		static Singleton m_Instance;
		return m_Instance;
	}*/

	int GetTest()
	{
		return m_Test;
	}

private:
	Singleton(){ m_Test = 10; };
	Singleton(const Singleton &tmp) {} 
	Singleton operator =(const Singleton &tmp){}
	int m_Test;
};

int main(int argc , char *argv [])
{
	Singleton *singletonObj = Singleton ::GetInstance();
	cout<<singletonObj->GetTest()<<endl;

	/*Singleton singletonObj = Singleton ::GetInstance();
	cout<<singletonObj.GetTest()<<endl;*/
}
按照你的回答,我进行了测试。麻烦确认我的测试代码是否正确。如果测试代码是正确的,我想确实避免的对象的拷贝。 2.
#include <iostream>
using namespace std;
 
class Singleton
{
public:
    static Singleton *GetInstance()
    {
        if (m_Instance == NULL)
        {
            m_Instance = new Singleton();
        }
        return m_Instance;
    }
 
    int GetTest()
    {
        return m_Test;
    }
 
private:
    Singleton(){ m_Test = 10; }
    static Singleton *m_Instance;
    int m_Test;
 
    // This is important
    class GC
    {
    public:
        ~GC()
        {
            // We can destory all the resouce here, eg:db connector, file handle and so on
            if (m_Instance != NULL)
            {
                delete m_Instance;
                m_Instance = NULL;
            }
        }
    };
    static GC gc;
};
 
Singleton *Singleton::m_Instance = NULL;
 
int main(int argc, char *argv[])
{
    Singleton *singletonObj = Singleton::GetInstance();
    cout<<singletonObj->GetTest()<<endl;
     
    return 0;
}
该代码中定义了static GC gc;在程序结束时,它会调用~GC进行析构吗?在我的实际测试中,它并没有调用析构函数,就连基本的构造函数都没有调用。但是,如果将static关键字去掉,它会调用构造函数,但是,析构函数还是没有调用。按照你的理解,能否说明一下。 以上,是小弟的问题,拜托回答一下。谢谢了。[/quote] 1,返回引用,否则每次调用返回都是原静态对象的副本,谈何单实例? 2,必须在类外面定义静态成员gc,否则对象都没有,谈何析构?
dyw 2013-11-21
  • 打赏
  • 举报
回复
引用 16 楼 vipygd 的回复:
[quote=引用 14 楼 dyw 的回复:] [quote=引用 12 楼 vipygd 的回复:] [quote=引用 10 楼 dyw 的回复:] [quote=引用 6 楼 vipygd 的回复:] [quote=引用 3 楼 dyw 的回复:] [quote=引用 2 楼 vipygd 的回复:] [quote=引用 1 楼 dyw 的回复:] 这样是所谓的RAll机制自动销毁,也可以定义一个静态函数释放单实例指针,但需要你记得调用它。还有的实现方法是在静态函数内定义静态局部对象。
谢谢你的回答,对于所谓的RAll机制自动销毁和在静态函数内定义静态局部对象,有一些不清楚?能否进行说明一下?拜托了。在静态函数内定义静态局部对象是什么机制?[/quote] 1、RAll机制:利用c++的构造与析构特性自动回收资源,智能指针就属于这一类,还有自动关闭句柄等。 2、利用静态局部对象的单例模式:
static A& getInstance()
{
   static A a;
   return a;
}
[/quote] 智能指针,不是使用的引用计数么?这个a貌似没有被释放。我个人认为。如果有不对的地方,请指正,拜托了。[/quote] 有引用计数的智能指针是共享型的,当共享计数为0时自动释放。 a为什么没有被释放?你觉得这个静态对象的析构函数不会被调用吗?为什么? 这里有些讨论:http://stackoverflow.com/questions/1463707/c-singleton-vs-global-static-object[/quote]
/*
#include <iostream>
using namespace std;

class Singleton
{
public:
	static Singleton *GetInstance()
	{
		if (m_Instance == NULL)
		{
			m_Instance = new Singleton();
		}
		return m_Instance;
	}

	int GetTest()
	{
		return m_Test;
	}

private:
	Singleton(){ m_Test = 10; }
	static Singleton *m_Instance;
	int m_Test;

	// This is important
	class GC
	{
	public:
		~GC()
		{
			// We can destory all the resouce here, eg:db connector, file handle and so on
			if (m_Instance != NULL)
			{
				cout<<"Call the GC's destructor"<<endl;
				delete m_Instance;
				m_Instance = NULL;
			}
		}
	};
	static GC gc;
};

Singleton *Singleton::m_Instance = NULL;

int main(int argc, char *argv[])
{
	Singleton *singletonObj = Singleton::GetInstance();
	cout<<singletonObj->GetTest()<<endl;
	
	return 0;
}
谢谢你推荐的文章,但是,这个是个demo,那么cout<<"Call the GC's destructor"<<endl;会执行的,但是实际上,这个语句没有被执行;拜托解释一下。谢谢了。 你推荐的文章中,有人提到以下实现是最好的单例实现:
Printer & thePrinter() {
    static Printer printer;
    return printer;
}
但是,这种单例实现在实际应用中会遇到对象的拷贝问题,你有遇到过吗? 如果修改成以下是否可以:
Printer *thePrinter() {
    static Printer printer;
    return &printer;
}
希望能得到你的指导,谢谢。再次谢谢你耐心的指导。[/quote] 推荐使用只有三行代码的这种实现方式。这种方式在Qt的源码中也很常见。我一般都这样使用。 至于修改为返回指针,同样阻止不了复制行为,想想为什么? 要阻止复制行为,声明拷贝构造函数、赋值函数为私有即可。对于单例模式,由于不允许直接构造,因此构造函数也是私有的。[/quote] 再次感谢你耐心的回答,能给我这么详细的讲解,非常感谢。 对于你的回答,我还是有如下疑问,麻烦你能给我回答一下以下问题,拜托了。 > 至于修改为返回指针,同样阻止不了复制行为,想想为什么?
#include <iostream>
using namespace std;

class Singleton
{
public:
	static Singleton *GetInstance()
	{
		static Singleton m_Instance;
		return &m_Instance;
	}

	/*static Singleton GetInstance()
	{
		static Singleton m_Instance;
		return m_Instance;
	}*/

	int GetTest()
	{
		return m_Test;
	}

private:
	Singleton(){ m_Test = 10; };
	Singleton(const Singleton &tmp) {} 
	Singleton operator =(const Singleton &tmp){}
	int m_Test;
};

int main(int argc , char *argv [])
{
	Singleton *singletonObj = Singleton ::GetInstance();
	cout<<singletonObj->GetTest()<<endl;

	/*Singleton singletonObj = Singleton ::GetInstance();
	cout<<singletonObj.GetTest()<<endl;*/
}
按照你的回答,我进行了测试。麻烦确认我的测试代码是否正确。如果测试代码是正确的,我想确实避免的对象的拷贝。 2.
#include <iostream>
using namespace std;
 
class Singleton
{
public:
    static Singleton *GetInstance()
    {
        if (m_Instance == NULL)
        {
            m_Instance = new Singleton();
        }
        return m_Instance;
    }
 
    int GetTest()
    {
        return m_Test;
    }
 
private:
    Singleton(){ m_Test = 10; }
    static Singleton *m_Instance;
    int m_Test;
 
    // This is important
    class GC
    {
    public:
        ~GC()
        {
            // We can destory all the resouce here, eg:db connector, file handle and so on
            if (m_Instance != NULL)
            {
                delete m_Instance;
                m_Instance = NULL;
            }
        }
    };
    static GC gc;
};
 
Singleton *Singleton::m_Instance = NULL;
 
int main(int argc, char *argv[])
{
    Singleton *singletonObj = Singleton::GetInstance();
    cout<<singletonObj->GetTest()<<endl;
     
    return 0;
}
该代码中定义了static GC gc;在程序结束时,它会调用~GC进行析构吗?在我的实际测试中,它并没有调用析构函数,就连基本的构造函数都没有调用。但是,如果将static关键字去掉,它会调用构造函数,但是,析构函数还是没有调用。按照你的理解,能否说明一下。 以上,是小弟的问题,拜托回答一下。谢谢了。[/quote] 1. 无需实现以下函数,把花括弧去掉。
    Singleton(const Singleton &tmp);
    Singleton operator =(const Singleton &tmp);
你也可以让单例函数返回指针,跟返回引用区别不大,只是调用该对象的方法时使用的操作符不同。返回引用的话,可以很清楚的知道不用关心这个对象的释放问题。 2. 我也怀疑这种实现方式的有效性,不知道你在哪里看到的。 此外,《Modern C++ Design》一书中有singleton的实作,可找来一看。
果冻想 2013-11-21
  • 打赏
  • 举报
回复
引用 14 楼 dyw 的回复:
[quote=引用 12 楼 vipygd 的回复:] [quote=引用 10 楼 dyw 的回复:] [quote=引用 6 楼 vipygd 的回复:] [quote=引用 3 楼 dyw 的回复:] [quote=引用 2 楼 vipygd 的回复:] [quote=引用 1 楼 dyw 的回复:] 这样是所谓的RAll机制自动销毁,也可以定义一个静态函数释放单实例指针,但需要你记得调用它。还有的实现方法是在静态函数内定义静态局部对象。
谢谢你的回答,对于所谓的RAll机制自动销毁和在静态函数内定义静态局部对象,有一些不清楚?能否进行说明一下?拜托了。在静态函数内定义静态局部对象是什么机制?[/quote] 1、RAll机制:利用c++的构造与析构特性自动回收资源,智能指针就属于这一类,还有自动关闭句柄等。 2、利用静态局部对象的单例模式:
static A& getInstance()
{
   static A a;
   return a;
}
[/quote] 智能指针,不是使用的引用计数么?这个a貌似没有被释放。我个人认为。如果有不对的地方,请指正,拜托了。[/quote] 有引用计数的智能指针是共享型的,当共享计数为0时自动释放。 a为什么没有被释放?你觉得这个静态对象的析构函数不会被调用吗?为什么? 这里有些讨论:http://stackoverflow.com/questions/1463707/c-singleton-vs-global-static-object[/quote]
/*
#include <iostream>
using namespace std;

class Singleton
{
public:
	static Singleton *GetInstance()
	{
		if (m_Instance == NULL)
		{
			m_Instance = new Singleton();
		}
		return m_Instance;
	}

	int GetTest()
	{
		return m_Test;
	}

private:
	Singleton(){ m_Test = 10; }
	static Singleton *m_Instance;
	int m_Test;

	// This is important
	class GC
	{
	public:
		~GC()
		{
			// We can destory all the resouce here, eg:db connector, file handle and so on
			if (m_Instance != NULL)
			{
				cout<<"Call the GC's destructor"<<endl;
				delete m_Instance;
				m_Instance = NULL;
			}
		}
	};
	static GC gc;
};

Singleton *Singleton::m_Instance = NULL;

int main(int argc, char *argv[])
{
	Singleton *singletonObj = Singleton::GetInstance();
	cout<<singletonObj->GetTest()<<endl;
	
	return 0;
}
谢谢你推荐的文章,但是,这个是个demo,那么cout<<"Call the GC's destructor"<<endl;会执行的,但是实际上,这个语句没有被执行;拜托解释一下。谢谢了。 你推荐的文章中,有人提到以下实现是最好的单例实现:
Printer & thePrinter() {
    static Printer printer;
    return printer;
}
但是,这种单例实现在实际应用中会遇到对象的拷贝问题,你有遇到过吗? 如果修改成以下是否可以:
Printer *thePrinter() {
    static Printer printer;
    return &printer;
}
希望能得到你的指导,谢谢。再次谢谢你耐心的指导。[/quote] 推荐使用只有三行代码的这种实现方式。这种方式在Qt的源码中也很常见。我一般都这样使用。 至于修改为返回指针,同样阻止不了复制行为,想想为什么? 要阻止复制行为,声明拷贝构造函数、赋值函数为私有即可。对于单例模式,由于不允许直接构造,因此构造函数也是私有的。[/quote] 再次感谢你耐心的回答,能给我这么详细的讲解,非常感谢。 对于你的回答,我还是有如下疑问,麻烦你能给我回答一下以下问题,拜托了。 > 至于修改为返回指针,同样阻止不了复制行为,想想为什么?
#include <iostream>
using namespace std;

class Singleton
{
public:
	static Singleton *GetInstance()
	{
		static Singleton m_Instance;
		return &m_Instance;
	}

	/*static Singleton GetInstance()
	{
		static Singleton m_Instance;
		return m_Instance;
	}*/

	int GetTest()
	{
		return m_Test;
	}

private:
	Singleton(){ m_Test = 10; };
	Singleton(const Singleton &tmp) {} 
	Singleton operator =(const Singleton &tmp){}
	int m_Test;
};

int main(int argc , char *argv [])
{
	Singleton *singletonObj = Singleton ::GetInstance();
	cout<<singletonObj->GetTest()<<endl;

	/*Singleton singletonObj = Singleton ::GetInstance();
	cout<<singletonObj.GetTest()<<endl;*/
}
按照你的回答,我进行了测试。麻烦确认我的测试代码是否正确。如果测试代码是正确的,我想确实避免的对象的拷贝。 2.
#include <iostream>
using namespace std;
 
class Singleton
{
public:
    static Singleton *GetInstance()
    {
        if (m_Instance == NULL)
        {
            m_Instance = new Singleton();
        }
        return m_Instance;
    }
 
    int GetTest()
    {
        return m_Test;
    }
 
private:
    Singleton(){ m_Test = 10; }
    static Singleton *m_Instance;
    int m_Test;
 
    // This is important
    class GC
    {
    public:
        ~GC()
        {
            // We can destory all the resouce here, eg:db connector, file handle and so on
            if (m_Instance != NULL)
            {
                delete m_Instance;
                m_Instance = NULL;
            }
        }
    };
    static GC gc;
};
 
Singleton *Singleton::m_Instance = NULL;
 
int main(int argc, char *argv[])
{
    Singleton *singletonObj = Singleton::GetInstance();
    cout<<singletonObj->GetTest()<<endl;
     
    return 0;
}
该代码中定义了static GC gc;在程序结束时,它会调用~GC进行析构吗?在我的实际测试中,它并没有调用析构函数,就连基本的构造函数都没有调用。但是,如果将static关键字去掉,它会调用构造函数,但是,析构函数还是没有调用。按照你的理解,能否说明一下。 以上,是小弟的问题,拜托回答一下。谢谢了。
go_seesea 2013-11-21
  • 打赏
  • 举报
回复
引用 1 楼 dyw 的回复:
这样是所谓的RAll机制自动销毁,也可以定义一个静态函数释放单实例指针,但需要你记得调用它。还有的实现方法是在静态函数内定义静态局部对象。
我的问题是:这个RAII机制有用吗?单例模式的成员变量本身不就是静态的吗?按这个说法系统退出时会自动析构单例类的静态成员,从而调用单例类的析构函数,所以,所谓的析构函数中的IO释放等等不都完成了?剩下的另一个问题是delete操作符和析构函数的区别,引用wiki百科上“In the C++ programming language, the delete operator calls the destructor of the given argument, and returns memory allocated by new back to the heap.”,也就是说delete的另一个作用是把new出来的内存还给堆,但是系统退出时进程的虚拟内存被全部释放,全局变量的地址空间和栈、堆空间都不复存在了还有必要delete吗? 另一个问题是:在动态库中该机制是否有效?进程退出时卸载动态库,动态库中的静态成员是否也被系统自动析构?
dyw 2013-11-21
  • 打赏
  • 举报
回复
引用 12 楼 vipygd 的回复:
[quote=引用 10 楼 dyw 的回复:] [quote=引用 6 楼 vipygd 的回复:] [quote=引用 3 楼 dyw 的回复:] [quote=引用 2 楼 vipygd 的回复:] [quote=引用 1 楼 dyw 的回复:] 这样是所谓的RAll机制自动销毁,也可以定义一个静态函数释放单实例指针,但需要你记得调用它。还有的实现方法是在静态函数内定义静态局部对象。
谢谢你的回答,对于所谓的RAll机制自动销毁和在静态函数内定义静态局部对象,有一些不清楚?能否进行说明一下?拜托了。在静态函数内定义静态局部对象是什么机制?[/quote] 1、RAll机制:利用c++的构造与析构特性自动回收资源,智能指针就属于这一类,还有自动关闭句柄等。 2、利用静态局部对象的单例模式:
static A& getInstance()
{
   static A a;
   return a;
}
[/quote] 智能指针,不是使用的引用计数么?这个a貌似没有被释放。我个人认为。如果有不对的地方,请指正,拜托了。[/quote] 有引用计数的智能指针是共享型的,当共享计数为0时自动释放。 a为什么没有被释放?你觉得这个静态对象的析构函数不会被调用吗?为什么? 这里有些讨论:http://stackoverflow.com/questions/1463707/c-singleton-vs-global-static-object[/quote]
/*
#include <iostream>
using namespace std;

class Singleton
{
public:
	static Singleton *GetInstance()
	{
		if (m_Instance == NULL)
		{
			m_Instance = new Singleton();
		}
		return m_Instance;
	}

	int GetTest()
	{
		return m_Test;
	}

private:
	Singleton(){ m_Test = 10; }
	static Singleton *m_Instance;
	int m_Test;

	// This is important
	class GC
	{
	public:
		~GC()
		{
			// We can destory all the resouce here, eg:db connector, file handle and so on
			if (m_Instance != NULL)
			{
				cout<<"Call the GC's destructor"<<endl;
				delete m_Instance;
				m_Instance = NULL;
			}
		}
	};
	static GC gc;
};

Singleton *Singleton::m_Instance = NULL;

int main(int argc, char *argv[])
{
	Singleton *singletonObj = Singleton::GetInstance();
	cout<<singletonObj->GetTest()<<endl;
	
	return 0;
}
谢谢你推荐的文章,但是,这个是个demo,那么cout<<"Call the GC's destructor"<<endl;会执行的,但是实际上,这个语句没有被执行;拜托解释一下。谢谢了。 你推荐的文章中,有人提到以下实现是最好的单例实现:
Printer & thePrinter() {
    static Printer printer;
    return printer;
}
但是,这种单例实现在实际应用中会遇到对象的拷贝问题,你有遇到过吗? 如果修改成以下是否可以:
Printer *thePrinter() {
    static Printer printer;
    return &printer;
}
希望能得到你的指导,谢谢。再次谢谢你耐心的指导。[/quote] 推荐使用只有三行代码的这种实现方式。这种方式在Qt的源码中也很常见。我一般都这样使用。 至于修改为返回指针,同样阻止不了复制行为,想想为什么? 要阻止复制行为,声明拷贝构造函数、赋值函数为私有即可。对于单例模式,由于不允许直接构造,因此构造函数也是私有的。
xiaohuh421 2013-11-21
  • 打赏
  • 举报
回复
单例模式有很多种实现方式, 你这只是其中一种. 注意: 对于单列模式, 要注意线程安全. 线程安全的单列需要在GetInstance中加锁. class CSingleton { private: CSingleton() //构造函数是私有的 { } CSingleton(const CSingleton &); CSingleton & operator = (const CSingleton &); public: static CSingleton & GetInstance() { static CSingleton instance; //局部静态变量 return instance; } }; class CSingleton { private: CSingleton() //构造函数是私有的 { } public: static CSingleton * GetInstance() { static CSingleton instance; //局部静态变量 return &instance; } }; class CSingleton { private: CSingleton() { } static CSingleton *m_pInstance; class CGarbo //它的唯一工作就是在析构函数中删除CSingleton的实例 { public: ~CGarbo() { if(CSingleton::m_pInstance) delete CSingleton::m_pInstance; } }; static CGarbo Garbo; //定义一个静态成员变量,程序结束时,系统会自动调用它的析构函数 public: static CSingleton * GetInstance() { if(m_pInstance == NULL) //判断是否第一次调用 m_pInstance = new CSingleton(); return m_pInstance; } };
果冻想 2013-11-20
  • 打赏
  • 举报
回复
引用 10 楼 dyw 的回复:
[quote=引用 6 楼 vipygd 的回复:] [quote=引用 3 楼 dyw 的回复:] [quote=引用 2 楼 vipygd 的回复:] [quote=引用 1 楼 dyw 的回复:] 这样是所谓的RAll机制自动销毁,也可以定义一个静态函数释放单实例指针,但需要你记得调用它。还有的实现方法是在静态函数内定义静态局部对象。
谢谢你的回答,对于所谓的RAll机制自动销毁和在静态函数内定义静态局部对象,有一些不清楚?能否进行说明一下?拜托了。在静态函数内定义静态局部对象是什么机制?[/quote] 1、RAll机制:利用c++的构造与析构特性自动回收资源,智能指针就属于这一类,还有自动关闭句柄等。 2、利用静态局部对象的单例模式:
static A& getInstance()
{
   static A a;
   return a;
}
[/quote] 智能指针,不是使用的引用计数么?这个a貌似没有被释放。我个人认为。如果有不对的地方,请指正,拜托了。[/quote] 有引用计数的智能指针是共享型的,当共享计数为0时自动释放。 a为什么没有被释放?你觉得这个静态对象的析构函数不会被调用吗?为什么? 这里有些讨论:http://stackoverflow.com/questions/1463707/c-singleton-vs-global-static-object[/quote]
/*
#include <iostream>
using namespace std;

class Singleton
{
public:
	static Singleton *GetInstance()
	{
		if (m_Instance == NULL)
		{
			m_Instance = new Singleton();
		}
		return m_Instance;
	}

	int GetTest()
	{
		return m_Test;
	}

private:
	Singleton(){ m_Test = 10; }
	static Singleton *m_Instance;
	int m_Test;

	// This is important
	class GC
	{
	public:
		~GC()
		{
			// We can destory all the resouce here, eg:db connector, file handle and so on
			if (m_Instance != NULL)
			{
				cout<<"Call the GC's destructor"<<endl;
				delete m_Instance;
				m_Instance = NULL;
			}
		}
	};
	static GC gc;
};

Singleton *Singleton::m_Instance = NULL;

int main(int argc, char *argv[])
{
	Singleton *singletonObj = Singleton::GetInstance();
	cout<<singletonObj->GetTest()<<endl;
	
	return 0;
}
谢谢你推荐的文章,但是,这个是个demo,那么cout<<"Call the GC's destructor"<<endl;会执行的,但是实际上,这个语句没有被执行;拜托解释一下。谢谢了。 你推荐的文章中,有人提到以下实现是最好的单例实现:
Printer & thePrinter() {
    static Printer printer;
    return printer;
}
但是,这种单例实现在实际应用中会遇到对象的拷贝问题,你有遇到过吗? 如果修改成以下是否可以:
Printer *thePrinter() {
    static Printer printer;
    return &printer;
}
希望能得到你的指导,谢谢。再次谢谢你耐心的指导。
果冻想 2013-11-20
  • 打赏
  • 举报
回复
引用 9 楼 AzraelLamber 的回复:
[quote=引用 5 楼 vipygd 的回复:] 谢谢你的回答。让我受益匪浅,我接着有如下疑问,你说到:静态对象和全局对象都会在程序结束时被系统负责析构。在程序结束时,在程序结束时,会释放该程序占用的所有资源。还有必要认为去控制内存的释放吗?
再强调一下: 至于意义嘛,你new的指针,你不负责释放你不觉得过分么?这是良好,安全的编程习惯。 你的类里简单,就是开辟了点内存,退出就销毁了,是无所谓,但是如果稍微复杂点呢?和硬件建立了个连接没有关闭?锁定了系统的资源没有解锁?没有给服务器发退出消息?你觉得合理么?[/quote] 谢谢你的指导,真的非常感谢。
dyw 2013-11-20
  • 打赏
  • 举报
回复
引用 6 楼 vipygd 的回复:
[quote=引用 3 楼 dyw 的回复:] [quote=引用 2 楼 vipygd 的回复:] [quote=引用 1 楼 dyw 的回复:] 这样是所谓的RAll机制自动销毁,也可以定义一个静态函数释放单实例指针,但需要你记得调用它。还有的实现方法是在静态函数内定义静态局部对象。
谢谢你的回答,对于所谓的RAll机制自动销毁和在静态函数内定义静态局部对象,有一些不清楚?能否进行说明一下?拜托了。在静态函数内定义静态局部对象是什么机制?[/quote] 1、RAll机制:利用c++的构造与析构特性自动回收资源,智能指针就属于这一类,还有自动关闭句柄等。 2、利用静态局部对象的单例模式:
static A& getInstance()
{
   static A a;
   return a;
}
[/quote] 智能指针,不是使用的引用计数么?这个a貌似没有被释放。我个人认为。如果有不对的地方,请指正,拜托了。[/quote] 有引用计数的智能指针是共享型的,当共享计数为0时自动释放。 a为什么没有被释放?你觉得这个静态对象的析构函数不会被调用吗?为什么? 这里有些讨论:http://stackoverflow.com/questions/1463707/c-singleton-vs-global-static-object
浮世修 2013-11-20
  • 打赏
  • 举报
回复
引用 5 楼 vipygd 的回复:
谢谢你的回答。让我受益匪浅,我接着有如下疑问,你说到:静态对象和全局对象都会在程序结束时被系统负责析构。在程序结束时,在程序结束时,会释放该程序占用的所有资源。还有必要认为去控制内存的释放吗?
再强调一下: 至于意义嘛,你new的指针,你不负责释放你不觉得过分么?这是良好,安全的编程习惯。 你的类里简单,就是开辟了点内存,退出就销毁了,是无所谓,但是如果稍微复杂点呢?和硬件建立了个连接没有关闭?锁定了系统的资源没有解锁?没有给服务器发退出消息?你觉得合理么?
5t4rk 2013-11-20
  • 打赏
  • 举报
回复
#ifndef _SINGLETON_H_ 
#define _SINGLETON_H_
#include <iostream>
using namespace std;
class Singleton 
        { 
 public: 
                static Singleton* Instance();
 protected:

        Singleton();//此处声明为了保护 则无法实现继承
private: 
        static Singleton* _instance;
        };
#endif //~_SINGLETON_H_
#include "Singleton.h"
#include <iostream> 
using namespace std;

Singleton* Singleton::_instance = 0;

Singleton::Singleton() 
        { 
        cout<<"Singleton...."<<endl; 
        }

Singleton* Singleton::Instance()
        { 
        if (_instance == 0) 
                { 
                _instance = new Singleton(); 
                }

return _instance;
        }
        //创建全局唯一一个对象
int main(int argc,char* argv[]) 
        { 
        Singleton* sgn = Singleton::Instance();
       // Singleton* sgn = Singleton::Instance();
        //不会再创建了 因为_instance=0才创建一旦创建就不在new 了
        system("pause");
        return 0; 
        }
taodm 2013-11-20
  • 打赏
  • 举报
回复 1
楼主,自己去买本《modern c++ design》翻到singleton模式的章节认真啃啃。 网上的东西就少看吧,误导比正导多多了。
果冻想 2013-11-20
  • 打赏
  • 举报
回复
引用 3 楼 dyw 的回复:
[quote=引用 2 楼 vipygd 的回复:] [quote=引用 1 楼 dyw 的回复:] 这样是所谓的RAll机制自动销毁,也可以定义一个静态函数释放单实例指针,但需要你记得调用它。还有的实现方法是在静态函数内定义静态局部对象。
谢谢你的回答,对于所谓的RAll机制自动销毁和在静态函数内定义静态局部对象,有一些不清楚?能否进行说明一下?拜托了。在静态函数内定义静态局部对象是什么机制?[/quote] 1、RAll机制:利用c++的构造与析构特性自动回收资源,智能指针就属于这一类,还有自动关闭句柄等。 2、利用静态局部对象的单例模式:
static A& getInstance()
{
   static A a;
   return a;
}
[/quote] 智能指针,不是使用的引用计数么?这个a貌似没有被释放。我个人认为。如果有不对的地方,请指正,拜托了。
果冻想 2013-11-20
  • 打赏
  • 举报
回复
引用 4 楼 AzraelLamber 的回复:
[quote=引用 2 楼 vipygd 的回复:] 谢谢你的回答,对于所谓的RAll机制自动销毁和在静态函数内定义静态局部对象,有一些不清楚?能否进行说明一下?拜托了。在静态函数内定义静态局部对象是什么机制?
和你的代码原理是一样的,静态对象和全局对象都会在程序结束时被系统负责析构。 至于RALL是神马,百度不到。。。 至于意义嘛,你new的指针,你不负责释放你不觉得过分么?这是良好,安全的编程习惯。[/quote] 谢谢你的回答。让我受益匪浅,我接着有如下疑问,你说到:静态对象和全局对象都会在程序结束时被系统负责析构。在程序结束时,在程序结束时,会释放该程序占用的所有资源。还有必要认为去控制内存的释放吗?
浮世修 2013-11-20
  • 打赏
  • 举报
回复
引用 2 楼 vipygd 的回复:
谢谢你的回答,对于所谓的RAll机制自动销毁和在静态函数内定义静态局部对象,有一些不清楚?能否进行说明一下?拜托了。在静态函数内定义静态局部对象是什么机制?
和你的代码原理是一样的,静态对象和全局对象都会在程序结束时被系统负责析构。 至于RALL是神马,百度不到。。。 至于意义嘛,你new的指针,你不负责释放你不觉得过分么?这是良好,安全的编程习惯。
dyw 2013-11-20
  • 打赏
  • 举报
回复
引用 2 楼 vipygd 的回复:
[quote=引用 1 楼 dyw 的回复:] 这样是所谓的RAll机制自动销毁,也可以定义一个静态函数释放单实例指针,但需要你记得调用它。还有的实现方法是在静态函数内定义静态局部对象。
谢谢你的回答,对于所谓的RAll机制自动销毁和在静态函数内定义静态局部对象,有一些不清楚?能否进行说明一下?拜托了。在静态函数内定义静态局部对象是什么机制?[/quote] 1、RAll机制:利用c++的构造与析构特性自动回收资源,智能指针就属于这一类,还有自动关闭句柄等。 2、利用静态局部对象的单例模式:
static A& getInstance()
{
   static A a;
   return a;
}
果冻想 2013-11-20
  • 打赏
  • 举报
回复
引用 1 楼 dyw 的回复:
这样是所谓的RAll机制自动销毁,也可以定义一个静态函数释放单实例指针,但需要你记得调用它。还有的实现方法是在静态函数内定义静态局部对象。
谢谢你的回答,对于所谓的RAll机制自动销毁和在静态函数内定义静态局部对象,有一些不清楚?能否进行说明一下?拜托了。在静态函数内定义静态局部对象是什么机制?
dyw 2013-11-20
  • 打赏
  • 举报
回复
这样是所谓的RAll机制自动销毁,也可以定义一个静态函数释放单实例指针,但需要你记得调用它。还有的实现方法是在静态函数内定义静态局部对象。

65,212

社区成员

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

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