C++进阶篇——特殊类设计
1. 设计一个不能被拷贝的类
拷贝只会发生在两个场景中:拷贝构造函数和赋值运算符重载,因此只需要禁止编译器生成这两个默认函数。
class CopyBan
{
CopyBan(const CopyBan&) = delete;
CopyBan& operator=(const CopyBan&) = delete;
};
2. 设计一个只能在堆上创建对象的类
只能在堆上创建意味着只能进行new
或者malloc
调用,就必须防止在栈上生成对象,需要禁止进行构造和拷贝构造的操作,我们将其设置为私有。
class HeapOnly
{
public:
static HeapOnly* CreateObj()
{
return new HeapOnly;
}
private:
HeapOnly() {}
HeapOnly(const HeapOnly&) = delete;
};
3. 设计一个只能在栈上创建对象
可以将构造函数私有化,然后设计静态方法在堆上创建对象并返回。然后禁用new
和delete
。
class StackOnly
{
public:
static StackOnly CreateObj()
{
return StackOnly();
}
// 禁掉operator new可以把下面用new 调用拷贝构造申请对象给禁掉
// StackOnly obj = StackOnly::CreateObj();
// StackOnly* ptr3 = new StackOnly(obj);
void* operator new(size_t size) = delete;
void operator delete(void* p) = delete;
private:
StackOnly()
:_a(0)
{}
private:
int _a;
};
4. 设计一个不能被继承的类
class A final
{
// ...
};
5. 设计一个类,只能创建一个对象
单例模式:一个类只能创建一个对象,即为单例模式,该模式可以保证系统中该类只有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。
-
饿汉模式:在程序启动的时候就创建一个唯一的实例对象。
// 优点:简单 // 缺点:可能会导致进程启动慢,并且如果有多个单例类会导致对象启动顺序不确定。 class Singleton { public: static Singleton* GetInstance() { return &m_instance; } private: Singleton() {} // 防止拷贝 Singleton(Singleton const&) = delete; Singleton& operator=(Singleton const&) = delete; static Singleton m_instance; }; Singleton Singleton::m_instance; // 在程序入口前完成初始化操作
-
懒汉模式:在使用的时候才进行创建对象。
// 优点:第一次使用实例对象的时候才会创建对象。进程启动无负载,多个单例实例启动顺序自由控制。 // 缺点:复杂 class Singleton { public: static Singleton* GetInstance() { // 如果是第一次创建对象,必须保证创建对象的过程是一步到位的,所以使用锁操作来保证线程安全 if(nullptr == m_pInstance) { m_mtx.lock(); if(nullptr == m_pInstance) m_pInstance = new Singleton(); m_mtx.unlock(); } return m_pInstance; } }; private: // 构造函数私有 Singleton(){}; // 防拷贝 Singleton(Singleton const&); Singleton& operator=(Singleton const&); static Singleton* m_pInstance; // 单例对象指针 static mutex m_mtx; //互斥锁 }; Singleton* Singleton::m_pInstance = nullptr; mutex Singleton::m_mtx;