设计一个类,不能被继承
cpp
// C++98版
class NonInherit
{
private:
NonInherit()
{}
};
// C++11版
class NonInherit final
{};
设计一个类,不能被拷贝
cpp
// C++98版
class CopyBan
{
private:
CopyBan(const CopyBan&);
CopyBan& operator=(const CopyBan&);
};
// C++11版
class CopyBan
{
CopyBan(const CopyBan&) = delete;
CopyBan& operator=(const CopyBan&) = delete;
};
设计一个类,只能在堆上创建对象
cpp
class HeapOnly
{
public:
// 提供一个公有的,获取对象的方式,对象被控制是new出来的
static HeapOnly* CreateObj()
{
return new HeapOnly;
}
// 防拷贝
HeapOnly(const HeapOnly&) = delete;
HeapOnly& operator=(const HeapOnly&) = delete;
private:
HeapOnly()
{}
};
设计一个类,只能在栈上创建对象
cpp
class StackOnly
{
public:
static StackOnly CreateObj()
{
return StackOnly();
}
// 不能防拷贝
//StackOnly(const StackOnly& so) = delete;
//StackOnly& operator=(const StackOnly& so) = delete;
void* operator new(size_t n) = delete;
private:
StackOnly()
{}
};
设计一个类,只能创建一个对象(单例模式)
单例模式是设计模式的一种。设计模式(Design Pattern)是代码设计经验总结的产物,就像人们所说的套路 。
当一个类只能创建一个对象,即所谓单例模式。单例模式用以保证系统中该类只有一个实例,被所有程序模块共享。
单例模式主要有两种实现模式:饿汉模式 和 懒汉模式。
饿汉模式
cpp
class Singleton
{
Singleton(Singleton const&) = delete;
Singleton& operator=(Singleton const&) = delete;
private:
// 构造函数私有化
Singleton()
{}
static Singleton _s; // 声明
};
// 定义
Singleton Singleton::_s;
cpp
class Singleton
{
public:
static Singleton* GetInstance()
{
return _ps;
}
Singleton(Singleton const&) = delete;
Singleton& operator=(Singleton const&) = delete;
private:
// 构造函数私有化
Singleton()
{}
static Singleton* _ps; // 声明
};
// 定义
Singleton* Singleton::_ps = new Singleton;
饿汉模式就是一开始(main函数之前)就把对象创建出来。
饿汉模式简单,没有线程安全问题。
如果一个程序中有多个单例,且有先后创建要求时,饿汉模式无法控制;而且饿汉模式初始化时任务很多,会影响程序启动速度。
懒汉模式
cpp
class Singleton
{
public:
static Singleton* GetInstance()
{
if (_ps == nullptr)
_ps = new Singleton;
return _ps;
}
// 内嵌垃圾回收类
class CGarbo
{
public:
~CGarbo() { delete _ps; }
};
private:
// 构造函数私有化
Singleton()
{}
static Singleton* _ps; // 声明
};
// 定义
Singleton* Singleton::_ps = nullptr;
// 定义回收对象,main函数结束后,调用析构函数释放单例对象
static Singleton::CGarbo cg;
懒汉模式是指第一次使用对象时才进行对象的创建。
懒汉模式的优缺点相对饿汉模式来说就是相反的,
即懒汉模式可以控制单例的先后创建顺序,因为使用时才创建实例,所以不影响程序的启动速度;
但懒汉模式的设计相对复杂,且存在线程安全问题。
对于单例对象的释放问题:
- 一般情况下,单例对象是不需要释放的。因为整个程序运行期间都有可能会用到它。
- 单例对象在进程正常结束后,会被释放。但有些场合也需要被释放,比如要通过单例对象析构时进行一些持久化(往文件、数据库写)操作。