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;
}
浙公网安备 33010602011771号