文章目录
- 不能被拷贝的类
 - 只能在堆上创建对象的类:
 - 方式一
 - 方式二
 
- 设计类只能创建栈对象
 - 实现类, 不能被继承
 - 单例模式设计
 - 饿汉模式
 - 懒汉模式
 - 线程安全问题
 
不能被拷贝的类
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 :
 
 
线程安全问题
对于懒汉模式, 当有两个线程同时第一个使用, 创建这个对象就有线程安全问题

单例模式最简单的写法:
 
 
 
欢迎随时来进行交流~~~



















