特殊类设计

个人主页:Lei宝啊 

愿所有美好如期而遇



不能被拷贝的类

这里我们介绍两种方式,使得一个类不能被拷贝

C++98---私有拷贝构造函数

class BanCopy_98
{
public:
	BanCopy_98() = default;

private:
	BanCopy_98(const BanCopy_98& copy);

	int _a;
};

这样,在类外,就无法对这个类的对象进行拷贝构造了。 

C++11---delete删除拷贝构造

class BanCopy_11
{

public:
	BanCopy_11() = default;
	BanCopy_11(const BanCopy_11& copy) = delete;

private:
	int _a;

};

这个就比较彻底,不仅在类外无法拷贝构造,类内也不可以。 

只能在堆上创建的类

私有构造函数

class HeapOnly
{
public:

	template<class ...Args>
	static HeapOnly* Create(Args ...args)
	{
		return new HeapOnly(args...);
	}

	void Destroy()
	{
		delete this;
	}

	~HeapOnly() { cout << "~HeapOnly" << endl; }
private:

	//构造私有,防止栈上创建对象
	HeapOnly(){}
	HeapOnly(int a, int b)
		:_a(a)
		,_b(b)
	{}

	//拷贝构造私有防止这种情况,HeapOnly ho2(*ho1); 
	HeapOnly(const HeapOnly & ho){}
	

	int _a;
	int _b;

};

私有析构函数

class HeapOnly
{
public:
	
	HeapOnly() {}
	HeapOnly(int a, int b)
		:_a(a)
		,_b(b)
	{}

	template<class ...Args>
	static HeapOnly* Create(Args ...args)
	{
		return new HeapOnly(args...);
	}

	void Destroy()
	{
		delete this;
	}

private:

	//拷贝构造私有防止这种情况,HeapOnly ho2(*ho1); 拷贝就在堆上深拷贝
	HeapOnly(const HeapOnly& ho) {}
	~HeapOnly() { cout << "~HeapOnly" << endl; }

	int _a;
	int _b;

};

因为如果在栈上创建对象,这个对象在类外会自动调用析构函数,而析构函数是私有的,所以这样也就防止了对象在栈上创建。 

只能在栈上创建的类

class StackOnly
{
public:
	StackOnly() {}
	StackOnly(int a, int b)
		:_a(a)
		,_b(b)
	{}

    template<class ...Args>
	static StackOnly Create(Args ...args)
	{
		return StackOnly(args...);
	}

	//无法防止,于是可以这样:StackOnly* ho1 = new StackOnly(ho);
	StackOnly(const StackOnly& ho) {}

	//new先调用operator new,然后才会调用构造。
	//这个operator new是我们重载的,所以new这个对象时优先调用我们这里的。
	void* operator new(size_t) = delete;
	~StackOnly() { cout << "~StackOnly" << endl; }


private:
	int _a;
	int _b;

};

 要创建只能在栈上创建的类,如果我们私有了构造,调用Create方法,那么返回这样一个对象需要拷贝构造,而一但需要拷贝构造,就会出现在堆上也能拷贝构造的情况.

如果我们不私有构造,那么堆上也就可以构造了,所以我们考虑ban掉operator new,new分为两个步骤,先调用operator new,然后才会调用对象的构造,所以我们在这个对象中重载一个类专属的operator new,这样在动态创建一个对象时,调用new时就会使用这个类中我们重载的operator new。

而我们只要ban掉operator new,构造和拷贝构造不私有也是没问题的。

不能被继承的类

C++98---私有基类构造函数

class Base_98
{
public:
	
private:
	Base_98() {}

protected:
	int _a;
};

C++11---final关键字

//C++11新增final关键字,修饰类,则类不可被继承,修饰虚函数,则虚函数不可被重写
class Base final
{
public:
	Base(){}

private:
	int _a;
};

单例对象类

什么叫单例对象,意思是在一个进程中,只存在一个这样的对象。

饿汉单例对象类

class hunger
{
public:

	static hunger* hungerCreate()
	{		
		return &hg;
	}

	bool set() {} //赋值
	bool add() {} //新增
	bool mod() {} //修改

	hunger(const hunger&) = delete;
	hunger& operator=(const hunger&) = delete;

	~hunger() { cout << "~hunger" << endl; }
private:
	hunger() { cout << "hunger create" << endl; }

	int _a;
	int _b;
	vector<string> vs;

	static hunger hg;
};

hunger hunger::hg;

但是饿汉有一个缺点就是,这个对象会在main函数前就创建,而main函数前没有多线程,于是如果这个对象初始化的数据很多,就会迟迟进不了main函数,无法执行我们的逻辑。 

懒汉单例对象类

我们这里实现的懒汉,不允许外界释放资源,由我们内部定义的gc对象释放。

class lazy
{
public:

	static lazy* lazyCreate()
	{
		if (hg == nullptr)
		{
			hg = new lazy;
		}

		return hg;
	}

	bool set(){} //赋值
	bool add(){} //新增
	bool mod(){} //修改

	lazy(const lazy&) = delete;
	lazy& operator=(const lazy&) = delete;

	void del()
	{
		delete hg;
		//delete this;
		hg = nullptr;
	}

private:

	lazy() { cout << "lazy create" << endl; }
	~lazy() { cout << "~lazy" << endl; }

	int _a;
	int _b;
	vector<string> vs;
	static lazy* hg;

	class gc
	{
	public:
		~gc()
		{
			hg->del();
		}
	};
	static gc auto_del_lazy;
};

//类型(需要类域) + 变量名(需要类域)
lazy* lazy::hg = nullptr;
lazy::gc lazy::auto_del_lazy;

这里的懒汉其实可以更加简单点,比如这样做:

class lazy
{
public:


	static lazy* lazyCreate()
	{	
		static lazy lz;	
		return &lz;
	}

	bool set() {} //赋值
	bool add() {} //新增
	bool mod() {} //修改

	lazy(const lazy&) = delete;
	lazy& operator=(const lazy&) = delete;

private:

	lazy() { cout << "lazy create" << endl; }
	~lazy() { cout << "~lazy" << endl; }

	int _a;
	int _b;
	vector<string> vs;

};

懒汉的目的就是在进入main函数后再初始化这个单例对象,这样即使它的数据量很大,但是进入main中,因为我们有了多线程,也就是卡一个线程,其他的线程不受影响,逻辑还可以继续执行下去。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lei宝啊

觉得博主写的有用就鼓励一下吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值