特殊类的设计

目录

1. 设计一个不能被拷贝的类

2. 设计一个只能在堆上创建的类

3. 设计一个只能在栈上创建的类

4. 设计一个不能被继承的类

5. 单例模式(设计一个类只创建一个对象)


1. 设计一个不能被拷贝的类

拷贝只会出现在拷贝构造函数赋值重载函数里面; 想要防止拷贝就要从这两个函数入手.

有c++98和c++11两种处理方法:

c++98直接将这两个函数变成私有成员(外部无法使用)的并且只声明不定义(防止内部拷贝);

c++11是不是有个关键字delete.

class NonCopy
{
private:
	NonCopy(const NonCopy&){}

	NonCopy& operator=(const NonCopy&) {} = delete;
};

 2. 设计一个只能在堆上创建的类

 想一下如何在堆上创建对象,:

(1) new或者static静态类型, 其实只要静态成员函数即可;

(2) 然后还要防止在栈上创建对象, 那么就要将拷贝构造函数和赋值重载函数都私有化, 并且只声明不定义.

 

class HeapOnly
{
public:
	static HeapOnly* creatobject()
	{
		return new HeapOnly;
	}

private:
	HeapOnly(){}

	HeapOnly(const HeapOnly&) = delete;
};

int main()
{
	//HeapOnly p;
	HeapOnly::creatobject();
	return 0;
}

 3. 设计一个只能在栈上创建的类

和上面更好相反, 需要把new和delete(这里不是c++11里的delete, 是销毁空间的)禁止掉, 以及私有化;

class StackOnly
{
public:
	static StackOnly creatobject()
	{
		return StackOnly();
	}

	void* operator new(size_t size) = delete;
	void operator delete(void * p) = delete;

private:
	StackOnly()
		:_a(0)
	{}
	int _a;
};

 4.设计一个不能被继承的类

c++98是直接将构造函数私有化, 子类就调不到基类的构造函数, 无法继承;

c++11是使用final关键字直接无法继承;

class NonInhert
{
public:
	static NonInhert CreatNonInhert()
	{
		return NonInhert();
	}
private:
	NonInhert()
	{}
};

class NonInhert final
{
  ...
}

5. 单例模式

啥是单例模式: 类中只能创建一个对象, 保证类中只有一个实例对象, 并提供一个访问它的全局访问点,该实例被所有程序模块共享.

有两种模式:饿汉模式和懒汉模式;

饿汉模式: 在使用之前就创建好;

懒汉模式; "现吃现做", 

 5.1饿汉模式

class Lazy
{
public:
	static Lazy* GetInstance()
	{
		return &_inst;
	}

	void Add(const string& key, const string& value)
	{
		_dict[key] = value;
	}

	void print()
	{
		for (auto& kv : _dict)
		{
			cout << kv.first << kv.second << endl;
		}
		cout << endl;
	}

private:
	Lazy(){}

	Lazy(const Lazy& aa) = delete;
	Lazy& operator=(const Lazy& aa) = delete;

	map<string, string> _dict;
	int _n = 0;

	static Lazy _inst;
};

Lazy Lazy::_inst;

int main()
{
	//Lazy aa1;

	Lazy::GetInstance()->Add("sort", "排序");
	Lazy::GetInstance()->Add("left", "左边");
	Lazy::GetInstance()->Add("right", "右边");
	Lazy::GetInstance()->print();

	/*Lazy copy(*Lazy::GetInstance());
	copy.print();
	
	//无法拷贝
	Lazy::GetInstance()->Add("left", "剩余");
	copy.print();
	Lazy::GetInstance()->print();*/

	//无法赋值
	//*Lazy::GetInstance() = *Lazy::GetInstance();
	return 0;
}

5.2 懒汉模式

class Singleton
{
public:
	static Singleton* GetInstance()
	{
		if (_inst == nullptr)
		{
			_inst = new Singleton;
		}
		return _inst;
	}

	void Add(const string& key, const string& value)
	{
		_dict[key] = value;
	}

	static void DelInstance()
	{
		if (_inst)
		{
			delete _inst;
			_inst = nullptr;
		}
	}


	void print()
	{
		for (auto& kv : _dict)
		{
			cout << kv.first << ":" << kv.second << endl;
		}
		cout << endl;
	}
private:
	//将构造函数和析构函数都私有化
	Singleton(){}
	~Singleton()
	{
		cout << "数据写入文件" << endl;
	}

	//拷贝构造和赋值重载都禁掉,不允许其他类实例出对象
	Singleton(const Singleton& aa) = delete;
	Singleton& operator=(const Singleton& aa) = delete;


	map<string, string> _dict;
	int _n = 0;
	class gc
	{
	public:
		~gc()
		{
			DelInstance();
		}
	};


	static Singleton* _inst;
	static Singleton _Singleton;
};

Singleton* Singleton::_inst = nullptr;


int main()
{
	
	Singleton::GetInstance()->Add("sort", "排序");
	Singleton::GetInstance()->Add("left", "左边");
	Singleton::GetInstance()->Add("right", "右边");
	Singleton::GetInstance()->print();

	Singleton::GetInstance()->Add("right", "xxx");
	Singleton::GetInstance()->print();
	
	Singleton::DelInstance();
	cout << "xxxxxxxxxxx" << endl;
	return 0;
}

5.3饿汉模式和懒汉模式的优缺点

饿汉模式:

        优点:实现简单;  缺点: 可能导致进程启动慢, 如果有多个单例那么实例的时候无法确定顺序;

懒汉模式:

        优点: 第一次使用实例对象时,创建对象。进程启动无负载。多个单例实例启动顺序自由控制。缺点:实现复杂.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值