编程语言中的特殊类的设计

20 篇文章 0 订阅

不能被拷贝的类

c++98 只声明(不生成, 编译器默认会生成, 有浅拷贝等的问题), 不实现, 并将其访问设为private
在这里插入图片描述

c++11使用=delete来限制

只能在堆上创建对象的类:

只能在堆上创建对象的类:

方式一

在这里插入图片描述delete使用会自动调用析构函数, 所以要销毁这个堆对象, 两种方式:
在这里插入图片描述第二种:
在这里插入图片描述

方式二

构造函数私有化, 提供一个函数用于创建对象
在这里插入图片描述
这样的方式并不完整, 利用拷贝构造还是能创建栈对象
在这里插入图片描述
所以这样的方式还要禁止掉拷贝构造函数才完美

HeapOnly(const HeapOnly& ho) = delete;

设计类只能创建栈对象

私有构造函数, 提供一个接口实现:
在这里插入图片描述但是防不住这样的写法:

在这里插入图片描述

这样也不能禁用拷贝构造, 因为在CreateObj中返回局部对象的值要调用拷贝构造,
所以最好的方式是:禁用new 或者是私有化

在这里插入图片描述

实现类, 不能被继承

1.构造函数私有化
在这里插入图片描述
2.c++11final修饰符

在这里插入图片描述

设计模式的概念:被反复使用, 被熟人知晓, 经过分类的, 代码设计经验的总结
(c++是不太关注的, 一般是应用方面比较关注(像Java等语言), 常见的有23种, 这边只细讲单例模式)
迭代器 包装器(适配器)也算设计模式

单例模式设计

思想:对构造函数进行操作

饿汉模式

提前(main函数启动前)准备好,随时getinsert
在类内创建一个该类的对象(此时不允许, 不允许这样的方式来声明), 并且把这个类的对象设为static, 静态的不在对象里面.
这个对象的内存属于静态区, 访问权限属于private, 属于是类内的成员, 此时是属于声明, 定义需要使用类外定义

在这里插入图片描述
他的对象获取就需要使用这个方式

在这里插入图片描述同时要禁用拷贝构造和赋值构造:

完整代码及演示

class A
{
public:
	static A* GetInsert()
	{
		return &_inst;
	}
	void Add(const string& s1, const string& s2)
	{
		_dict[s1] = s2;
	}
	void Print()
	{
		for (auto& e : _dict)
		{
			cout << e.first << ":" << e.second << endl;
		}
	}
private:
	A() {}
	A(const A& a) = delete;
	A& operator=(const A& a) = delete;
	map<string, string> _dict;
	static A _inst;//先声明
};
A A::_inst;//定义
int main()
{
	A::GetInsert()->Add("sort", "排序");
	A::GetInsert()->Add("right", "向右");
	A::GetInsert()->Add("left", "向左");
	
	A::GetInsert()->Print();

	return 0;
}

结果演示
在这里插入图片描述

优点:
相比懒汉模式, 实现简单, 线程安全
缺点:
可能导致进程启动慢, 创建的单例对象首先会初始化很多
如果两个单例有启动先后顺序, 饿汉模式下无法控制
(导致问题的本质都是对象在main函数之前创建的有关)

懒汉模式

第一次用的时候再去创建(现吃现做)
与上述大致一致, 指向对象的指针初始化为nullptr
在类内构造的接口函数:

在这里插入图片描述
其他无异:


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

		return _inst;
	}
	void Add(const string& s1, const string& s2)
	{
		_dict[s1] = s2;
	}
	void Print()
	{
		for (auto& e : _dict)
		{
			cout << e.first << ":" << e.second << endl;
		}
	}
private:
	B() {}
	B(const B& a) = delete;
	B& operator=(const B& a) = delete;
	map<string, string> _dict;
	static B* _inst;//先声明
};
B* B::_inst = nullptr;//定义
int main()
{
	B::GetInstance()->Add("sort", "排序");
	B::GetInstance()->Add("right", "向右");
	B::GetInstance()->Add("left", "向左");
	
	B::GetInstance()->Print();

	return 0;
}

结果演示:
在这里插入图片描述
懒汉模式下new出来的对象一般不需要进行释放, 进程正常退出会释放资源
但是终有万一: 有的操作下是在析构函数要把数据写入文件,期望是main函数结束自动调用
所以使用 :
1.智能指针
2.内部类(内部类是外部类的友元)
这边演示2 :
在这里插入图片描述
在这里插入图片描述

线程安全问题

对于懒汉模式, 当有两个线程同时第一个使用, 创建这个对象就有线程安全问题

在这里插入图片描述

单例模式最简单的写法:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

欢迎随时来进行交流~~~

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

温有情

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值