这是两种典型的懒汉模式(防止资源泄露)的实现,但不保证线程安全
- 类内嵌套自定义的用于释放资源的类
#include<iostream>
class Singleton
{
public:
static Singleton* get_singleton(){
if(Singleton::singleton == nullptr){
Singleton::singleton = new Singleton();
}
return Singleton::singleton;
}
private:
static Singleton* singleton;
private:
class Deletor
{
public:
Deletor(){
std::cout<<"Deletor is createed!\n";
}
~Deletor(){
if(Singleton::singleton != nullptr){
delete Singleton::singleton;
Singleton::singleton = nullptr;
}
}
};
private:
Singleton(){
static Deletor deletor;
std::cout<<"Ctor is called!\n";}
~Singleton(){std::cout<<"Dtor is called!\n";}
Singleton(const Singleton&);
Singleton(Singleton&&);
Singleton& operator=(const Singleton&);
};
Singleton* Singleton::singleton = nullptr;
void test()
{
Singleton::get_singleton();
}
int main()
{
test();
return 0;
}
运行结果:
- 使用智能指针std::shared_ptr
#include<iostream>
#include<memory>
#include<string>
class Singleton
{
public:
inline static Singleton* Getsingleton(){
if(Singleton::singleton.get() == nullptr){
Singleton::singleton.reset(new Singleton(),Singleton::DeleteFunction);
}
return Singleton::singleton.get();
}
inline static void ShowStr(){
std::cout<<Singleton::singleton->test_str<<std::endl;
}
private:
static std::shared_ptr<Singleton>singleton;
static std::string test_str;
private:
Singleton(){std::cout<<"Ctor is called!"<<std::endl;}
~Singleton(){}
Singleton(const Singleton&){}
Singleton(Singleton&&){}
Singleton& operator=(const Singleton&) = default;
private:
static void DeleteFunction(Singleton*);
};
std::shared_ptr<Singleton> Singleton::singleton(nullptr);
std::string Singleton::test_str = "test";
void Singleton::DeleteFunction(Singleton* ptr) {
delete ptr;
ptr = nullptr;
std::cout<<"Delete function is called!\n";
}
void test() {
Singleton::Getsingleton()->ShowStr();
}
int main(){
test();
return 0;
}
运行结果:
注意:
1.自定义了shared_ptr的删除器
2.为了与第一种做法统一,传入nullptr初始化,并调用reset()重新分配空间。也可以这样实现:
inline static Singleton* Getsingleton(){
return Singleton::singleton.get();
}
std::shared_ptr<Singleton> Singleton::singleton(new Singleton(),Singleton::DeleteFunction);