zoukankan      html  css  js  c++  java
  • singleton的内存泄漏及线程安全性问题

    原文链接:

    http://patmusing.blog.163.com/blog/static/135834960201002322226231/

    一、最简单的实现方式

    // Singleton.h
    
    // C++:最简单的方式实现Singleton设计模式
    
    #pragma once
    #include <string>
    #include <iostream>
    using namespace std;
    
    class Singleton
    {
    private:
    	Singleton()                                            // private构造函数
    	{
    		cout << "Singleton::Constructor" << endl;
    	}
    
    
    	static Singleton* sg;                             // 私有静态变量,其类型为Singleton*
    	// 形如Singleton sg;这样的声明会出编译时错误
    public:
    	static Singleton* getInstance()           // public成员函数getInstance()
    	{
    		cout << "Singleton::getInstance" << endl;
    		if(!sg)
    		{
    			sg = new Singleton();           // (1)在这个地方new了一个对象,但是在什么地方delete呢?
    		}
    		return sg;
    	}
    
    };
    
    
    #include "stdafx.h"
    
    #include "Singleton.h"
    
    // 用下面的方式对静态私有成员变量sg进行初始化,此时sg不指向任何对象
    Singleton* Singleton::sg = 0;
    int main(void)
    {
    	Singleton *sg = Singleton::getInstance();
    	return 0;
    }
    
    

    语句(1)中new了一个对象,但没有被delete,因此肯定会造成内存泄漏。

    二、使用auto_ptr来解决内存泄漏问题

    // Singleton.h
    
    #include <memory>
    
    #include <string>
    
    #include <iostream>
    
    using namespace std;
    
    // C++:使用auto_ptr实现Singleton设计模式
    class Singleton
    {
    private:
    	Singleton()	// private构造函数
    	{
    		cout << "Singleton::Constructor" << endl;
    	}
    	// 私有静态变量,其类型为auto_ptr<Singleton>
    	static auto_ptr<Singleton> sg;
    public:
    	// public成员函数getInstance()
    	static auto_ptr<Singleton> getInstance()
    	// 返回类型为auto_ptr<Singleton>
    	{
    		cout << "Singleton::getInstance" << endl;
    		if(!sg.get())	// 判断sg所指的对象是否为空
    		{
    			// 此处不能直接写成auto_ptr<Singleton> sg(new Singleton);
    			auto_ptr<Singleton> temp(new Singleton);
    			sg = temp;                                              
    		}
    		return sg;
    	}
    };
    #include "stdafx.h"
    
    // Singleton.cpp:测试Singleton的代码
    #include "Singleton.h"
    // 用下面的方式对静态私有成员变量sg进行初始化,此时sg不指向任何对象
    auto_ptr<Singleton> Singleton::sg;
    
    int main(void)
    {
    	// singleton就是我们需要的对象
    	auto_ptr<Singleton> singleton(Singleton::getInstance());
    	return 0;
    }
    

    三、基于模块的方法实现:

    进一步地,我们还可以将Singleton类,写成模板类,这样就可以更加灵活了。为此,我们另外增加一个类Student用来测试,Singleton模板类。

    //Singleton.h
    
    #include <memory>
    #include <string>
    #include <iostream>
    using namespace std;
    
    
    class Student
    {
    public:
    	Student(const string name = "Andrew", const int age = 7) : name(name), age(age)
    	{
    		cout << "constructor..." << endl;
    	}
    	void print_info() const
    	{
    		cout << "Name: " << name << ", Age: " << age << endl;
    	}
    
    private:
    	string name;
    	int age;
    
    };
    
    
    
    // Singleton模板类
    
    template<typename T>
    
    class Singleton
    {
    private:
    	Singleton()	// private构造函数
    	{
    		cout << "Singleton::Constructor" << endl;
    	}
    
    
    	static auto_ptr<T> sg;	// 私有静态变量,其类型为auto_ptr<T>
    
    public:
    	static auto_ptr<T> getInstance()	// public成员函数getInstance()
    	{	// 返回类型为auto_ptr<T>
    		cout << "Singleton::getInstance" << endl;
    		if(!sg.get())	// 判断sg所指的对象是否为空
    		{
    			// 此处不能直接写成auto_ptr<T> sg(new T);
    			auto_ptr<T> temp(new T);         
    			sg = temp;                                              
    		}
    		return sg;
    	}
    };
    
    
    // Singleton.cpp 测试代码
    #include "stdafx.h"
    #include "Singleton.h"
    
    // 用下面的方式对静态私有成员变量sg进行初始化,此时sg不指向任何对象
    
    auto_ptr<Student> Singleton<Student>::sg;
    int main(void)
    {
    	auto_ptr<Student> singleton(Singleton<Student>::getInstance());
    	singleton->print_info();
    	return 0;
    }
    
  • 相关阅读:
    Redis订阅和发布模式和Redis事务
    Redis介绍和环境安装
    Redis基本数据类型
    MongoDB导入导出以及数据库备份
    MongoDB-python的API手记
    MongoDB对应SQL语句
    判断是否微信浏览器访问并得到微信版本号
    windows 下编译php扩展库pecl里的扩展memcache
    用PHPExcel类读取excel文件的内容
    用excel.php类库导出excel文件
  • 原文地址:https://www.cnblogs.com/lilun/p/1818334.html
Copyright © 2011-2022 走看看