文章目录
- 不能被拷贝
- 只在堆上创建
- 只能在栈上创建
- 不能被继承
- [饿汉单例 程序启动前就创建好](#饿汉单例 程序启动前就创建好)
- [懒汉单例 需要的时候即调用GetInstance时再创建单例](#懒汉单例 需要的时候即调用GetInstance时再创建单例)
不能被拷贝
cpp
class CopyBan
{
public:
CopyBan()
{}
private:
// C++98
CopyBan(const CopyBan&);
CopyBan& operator=(const CopyBan&);
// C++11
CopyBan(const CopyBan&) = delete;
CopyBan& operator=(const CopyBan&) = delete;
};
- 私有:类外无法调用 类外无法定义
- 无定义:类内即使调用也无实现
只在堆上创建
析构函数私有化 + 提供销毁接口
cpp
class HeapOnly
{
public:
// 提供接口销毁堆上对象
void Destroy()
{
delete this;
}
private:
// 析构函数私有 导致无法在栈上创建对象
~HeapOnly()
{
cout << "~HeapOnly()" << endl;
}
};
int main()
{
HeapOnly* hp = new HeapOnly;
hp->Destroy();
return 0;
}
构造函数私有 + 提供静态成员函数
cpp
class HeapOnly
{
public:
static HeapOnly* CreateObj()
{
return new HeapOnly;
}
private:
HeapOnly()
{}
HeapOnly(const HeapOnly&) = delete;
HeapOnly& operator=(const HeapOnly&) = delete;
};
int main()
{
HeapOnly* hp = HeapOnly::CreateObj();
return 0;
}
只能在栈上创建
cpp
class StackOnly
{
public:
static StackOnly CreateObj()
{
StackOnly obj;
return obj;
}
private:
StackOnly()
{}
};
int main()
{
StackOnly st1 = StackOnly::CreateObj();
StackOnly* st2 = new StackOnly(st1);// error 这里仍然可以调用
return 0;
}
不能通过禁用拷贝构造,CreateObj()返回栈上的对象是传值返回,需要拷贝构造函数。
在类里面写一个 operator new 并禁掉。使用 new时,默认调的是全局的 new,但是如果我们在类中写一个 operator new,那么当我们 new 一个该类的对象时,会优先调用我们自己写的 operator new,所以我们只需要把自己写的 operator new 禁掉即可。
new = operator new() + 构造函数
cpp
class StackOnly
{
public:
static StackOnly CreateObj()
{
StackOnly obj;
return obj;
}
// 实现类专属的 operator new
void* operator new(size_t size) = delete;
private:
StackOnly()
{}
};
不能被继承
cpp
// C++98
class NonInherit
{
public:
static NonInherit GetInstance()
{
return NonInherit();
}
private:
NonInherit()
{}
};
// C++11
class NonInherit final
{
public:
NonInherit()
{}
private:
// ...
};
饿汉单例 程序启动前就创建好
程序启动前_inst静态对象就初始化完毕 之后使用该单例时调用GetInstancePtr()即可
cpp
class Singleton
{
public:
//static Singleton& GetInstance()
//{
// return inst;
//}
static Singleton* GetInstancePtr()
{
return &_inst;
}
private:
static Singleton _inst; // 声明
Singleton(){}
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
};
// 定义
Singleton Singleton::_inst;
指针版本
cpp
class Singleton
{
public:
static Singleton* GetPtrAtOnly()
{
return _ponly;
}
private:
static Singleton* _ponly;
Singleton() {}
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
};
Singleton* Singleton::_ponly = new Singleton;
int main()
{
Singleton* instPtr = Singleton::GetPtrAtOnly();
return 0;
}
懒汉单例 需要的时候即调用GetInstance时再创建单例
cpp
class Singleton
{
public:
static Singleton* GetInstance()
{
// error 线程不安全
//if (_inst == nullptr)
//{
// _inst = new Singleton;
//}
ok but 效率低
//_ptrmtx.lock();
//if (_inst == nullptr)
//{
// _inst = new Singleton;
//}
//_ptrmtx.unlock();
error 相当于没加锁
//if (_inst == nullptr)
//{
// _ptrmtx.lock();
// _inst = new Singleton;
// _ptrmtx.unlock();
//}
// ok
if (_inst == nullptr)
{
_ptrmtx.lock();
if (_inst == nullptr)
{
_inst = new Singleton;
}
_ptrmtx.unlock();
}
return _inst;
}
private:
static Singleton* _inst;
static mutex _ptrmtx;
Singleton(){}
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
};
mutex Singleton::_ptrmtx;
Singleton* Singleton::_inst = nullptr;
C++11后支持这样写且线程安全
cpp
// 懒汉
class Singleton
{
public:
static Singleton& GetInstance()
{
static Singleton instance;
return instance;
}
private:
Singleton() {}
~Singleton() {}
Singleton(const Singleton& s) = delete;
Singleton& operator=(const Singleton& s) = delete;
};
class Singleton2
{
public:
static Singleton2* GetPtrAtOnly()
{
static Singleton2 one;
return &one;
}
private:
Singleton2() {}
~Singleton2() {}
Singleton2(const Singleton2& s) = delete;
Singleton2& operator=(const Singleton2& s) = delete;
};
int main()
{
Singleton& singletonInstance = Singleton::GetInstance();
Singleton2* instPtr = Singleton2::GetPtrAtOnly();
return 0;
}