C++特殊类的设计
接下来我们设计一些C++的常用特殊类,同时加深对C++类和对象的理解
设计一个不能被拷贝的类
拷贝只会放生在两个场景中:拷贝构造函数
以及赋值运算符重载
,因此想要让一个类禁止拷贝,只需让该类不能调用拷贝构造函数以及赋值运算符重载即可。
C++98
将拷贝构造和赋值重载只私有声明
且不定义即可
分析:
- 设为私有:防止类外调用,还能防止类外定义重新实现拷贝功能
- 只声明不定义:防止类内成员函数对其调用
1
2
3
4
5
6
7//C++98
class NoCopy
{
private://设置成私有
NoCopy(const NoCopy&);
NoCopy& operator=(const NoCopy&);//只声明不定义
};
C++11
C++11扩展了delete
关键字的用法,可用于删除成员函数,尤其是删除默认成员函数
1 | //C++11 |
设计一个类,只能在堆上创建对象
既然涉及到类实例化成对象(如下图),势必绕不开构造函数,但实际上对类的设计者来说,通过控制构造函数来控制用户的行为难以实现。所以我们选择把拷贝构造函数
禁掉,把赋值运算重载
禁掉,把默认构造函数
私有化,然后单独提供静态成员函数
1 | class HeapOnly |
设计一个类,只能在栈上创建对象
除了要把构造函数私有化,还要把operator new
和operator delete
重载禁掉,然后提供在返回栈上创建的对象的静态成员函数
赋值运算符重载函数只返回栈上的对象,所以不用管它
1 | class StackOnly |
设计一个类,不能被继承
C++98
将构造函数私有化,派生类中调用不到基类的构造函数,就会继承失败
1 | class NoInherit |
C++11
C++11提供了final
关键字,被final
修饰的类不能被继承
1 | class InheritBan final |
设计一个类,只能创建一个对象(单例模式)
单例模式:
一个类只能创建一个对象,即单例模式,该模式可以保证系统中该类只有一个实例,并提供一个
访问它的全局访问点,该实例被所有程序模块共享。比如在某个服务器程序中,该服务器的配置
信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再
通过这个单例对象获取这些配置信息,这种方式简化了在复杂环境下的配置管理。
懒汉方式最核心的思想是 “延时加载”. 从而能够优化服务器的启动速度.
饿汉方式实现
1 | template <typename T> |
只要通过 Singleton
这个包装类来使用 T 对象, 则一个进程中只有一个static T
对象的实例.
懒汉方式实现
1 | template <typename T> |
存在一个严重的问题, 线程不安全
因为inst
是多个进程共享的资源,对其进行判空操作,也要用锁保护起来
线程安全的版本实现
1 | // 懒汉模式, 线程安全 |
特别注意
- 加锁解锁的位置
- 双重if判定,避免不必要的锁竞争
volatile
关键字防止过度优化