特殊类设计、单例模式

目录

1 特殊类设计

1.1 只能在堆上创建

1.2 只能在栈上创建

1.3 类不能被拷贝

1.4 类不能被继承

2 单例模式

2.1 饿汉模式

2.2 饱汉


1 特殊类设计

1.1 只能在堆上创建

        我们可以将无参构造函数设置为私有(不能delete,new还需要有无参构造)。

        提供一个公有函数来在堆上创建类。

        将拷贝构造delete,防止用户使用拷贝构造在栈上创建。

class A
{
public:
	static A* getA()
	{
		return new A;
	}
private:
	A() {};
	A(const A&) = delete;
};

1.2 只能在栈上创建

        在c++98中,将构造函数私有,在另外提供一个公共接口在栈上创建类。

class A
{
public:
	static A getA()
	{
		return A();
	}
private:
	A() {}
};

        由于上面那种方式还可以利用拷贝构造在堆上创建,如下方式:

A a = getA();
A* aa = new A(a);

        因为getA接口必须要用到拷贝构造,我们无法将拷贝构造私有或者delete。这时我们可以将new和delete操作符重载删除。

class A
{
public:
	static A getA()
	{
		return A();
	}
private:
	void* operator new(size_t) = delete;
	void operator delete(void*) = delete;
};

1.3 类不能被拷贝

        直接将拷贝构造和拷贝赋值设置为私有,或者在c++11中使用delete删除这连个成员函数。

class A
{
private:
	A(const A&) = delete;
	A& operator=(const A&) = delete;
};

1.4 类不能被继承

        最简单的做法就是在类名后加上final关键字,不过这是c++11的语法。如果只能是c++98,那么可以就构造函数设为私有

class A final
{};

class A
{
private:
    A();
};

2 单例模式

2.1 饿汉模式

        饿汉模式,就是在主函数执行前就已经创建好了实例。这样的做法缺点是无法在多单例创建时控制创建顺序,而且提早创建好实例会导致进程启动慢。其优点就是实现起来结构简单。

        其实现就是,将一般的构造、赋值都设置为私有或delete,另外提供公共接口来得到实例。需要注意公共接口设置为静态,否则没有实例来执行该接口创建第一个实例。私有属性_instance只能有一个,也应设置为静态的。

class Singleton
{
public:
	static Singleton& getInstance()
	{
		return _instance;
	}
private:
	Singleton() {}
	Singleton(const Singleton&) = delete;
	Singleton& operator=(const Singleton&) = delete;
	static Singleton _instance;
};
Singleton Singleton::_instance;

2.2 饱汉

        饱汉模式下下,在执行主程序前还没有创建实例,只有一个类类型的指针。在等到需要调用getInstance函数时才会进行实例创建。这样做的好处时,在进程启动时还未创建实例,加快进程启动速度。同时在多单例需要创建的情况,可以堆创建顺序进行控制。

        实现中需要注意的是,在判断单例是否已经创建后相应执行操作时,如果是多线程存在线程安全问题,需要加锁保证互斥。同时由于争夺锁时间消耗很大,为了提高代码效率,选择双判断减少对锁的争夺是更好的选择。

class Singleton
{
public:
	static Singleton* getInstance()
	{
		if (_pInstance == nullptr)
		{
			unique_lock<mutex> lock(_mtx);
			if (_pInstance == nullptr)
			{
				_pInstance = new Singleton;
			}
		}
		return _pInstance;
	}
private:
	Singleton() {}
	Singleton(const Singleton&) = delete;
	Singleton& operator=(const Singleton&) = delete;
	static Singleton* _pInstance;
	static mutex _mtx;
};
Singleton* Singleton::_pInstance = nullptr;
mutex Singleton::_mtx;

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值