特殊类的设计/单例模式

1.设计一个类不能拷贝

cpp 复制代码
class NotCopy
{
	//只声明不实现!
public:
private:
	NotCopy(const NotCopy&);
	NotCopy& operator=(const NotCopy&);

	//还有一种方法就是,c++11里面的加关键字delete
};

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

cpp 复制代码
class HeapOnly
{
public:
	//在这里我需要解释的是,肯定会有疑问为什么要用静态成员函数!
	//首先如果不用静态成员,普通函数放在类里面,如果在类外面想要被调用,首先得先实例化一个对象,然后才能调用!
	//然后因为我们为了实现在堆上创建对象,所以我们把构造函数和析构函数都进行了私有化,所以我们直接在栈上实例化对象是不可能了
	//因此我们没有了对象,现在要调用函数只能通过静态函数,因为静态函数它不需要通过对象调用,它自己就是可以看做类本身,加上作用域就可以了
	static HeapOnly* creat()
	{
		return new HeapOnly;
	}
	//静态函数属于类本身,不属于类的某个具体对象实例 ,它可以在不依赖对象实例的情况下被调用
	static void destory(HeapOnly* ptr)
	{
		delete ptr;
	}
	HeapOnly(const HeapOnly& hp) = delete;//这里把拷贝构造禁止掉!
private:
	//方案一,析构函数私有化!
	HeapOnly() {};
	~HeapOnly(){}

};

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

cpp 复制代码
class StackOnly
{
public:
	static StackOnly creat()
	{
		StackOnly obj;//这是在栈上面!
		return obj;
	}
	
	//如果你有实现一个专属类的operator new这样,它会优先调用自己的,不会去用库里面的!
	/*void* operator new(size_t size)
	{
		cout << "void* operator new" << endl;
		return malloc(size);
	}*/
	//所以通过上面这种操作,其实可以在自己的类里面把operator new给ban掉
	void* operator new(size_t size) = delete;
	/*~StackOnly();*/

private:
	StackOnly()
	{
		cout << "stackonly" << endl;
	}
};

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

cpp 复制代码
class NotInherit
{
	//方案一:构造函数私有化!
	// 因为当你父类构造函数私有化的时候,
	// 你子类创建对象的时候会初始化列表的时候先要调用父类构造函数初始化父类的变量!

	//方案二就是给类加final
private:
	NotInherit(){}
};

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

单例模式:

一个类只能创建一个对象,即单例模式,该模式可以保证系统中该类只有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。比如在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息,这种方式简化了在复杂环境下的配置管理。在我看来就是5v5,然后4打5有一个人去偷塔。

方案一:饿汉模式 -把对象提前创建好(程序启动时:main函数启动时),饿了直接吃!

想一想什么对象,可以在main函数前创建好,答案肯定可以想到全局变量!

优点:实现简单

缺点:进程启动慢,如果两个单例启动又先后顺序,饿汉模式无法控制!

cpp 复制代码
class A
{
public:
	static A* getInstance()
	{
		return &inst;
	}

	void add(const string& k,const string&v)
	{
		dict[k] = v;
	}
	void print()
	{
		for (auto e : dict)
		{
			cout << e.first <<": " << e.second << endl;
			
		}
		cout << endl;
	}
	
private:
	A(){}
	map<string, string> dict;
	int _n = 0;
	//把拷贝构造和赋值都禁掉,防止出现多个单例!
	A(const A& aa) = delete;
	A& operator=(const A& aa) = delete;
	static A inst;//这里是声明,静态成员变量要在类外面定义!
};

A A::inst;
//A inst;//全局!它是会有很多缺陷的,当你把全局放在.h里面多个cpp都能用到它,会出现连接错误的!

方案二:懒汉模式 -第一次用的时候再创建(现吃现做)

//new的懒汉对象一般不需要释放 进程自然结束,会自动释放资源;这里的释放资源其实是解除页表式的释放资源!

cpp 复制代码
class B
{
public:
	static B* getInstance()
	{
		if (inst == nullptr)
		{
			inst = new B;
			//如果写成 new B* ,得到的指针指向的是一个存储 B 类指针的空间,
			// 并非实际的 B 类对象,后续无法通过 inst 正确操作期望的单例对象。
		}
		return inst;
		
	}

	void add(const string& k, const string& v)
	{
		dict[k] = v;
	}
	void print()
	{
		for (auto e : dict)
		{
			cout << e.first << ": " << e.second << endl;

		}
		cout << endl;
	}
	//如果你需要手动释放资源你就调用下面的函数!,给它设置成静态全局变量是因为可以让整个类都能访问到!
	static void DelInstance()
	{
		if (inst)
		{
			delete inst;
			inst = nullptr;
		}
	}
private:
	B() {}
	map<string, string> dict;
	int _n = 0;
	//把拷贝构造和赋值都禁掉,防止出现多个单例!
	B(const B& bb) = delete;
	B& operator=(const B& bb) = delete;
	static B* inst;//这里是声明,静态成员变量要在类外面定义!

	//内部类,是外部类的的友元
	class del
	{
	public:
		~del()
		{
			DelInstance();
		}
	};
	static del D;//之所以有静态全局对象是因为,要触发del的析构函数,
	//而为什么用静态是因为只有静态成员其实是main程序结束后,系统开始清理资源时才会被释放
};

B* B::inst=nullptr;
B::del B:: D;

void test()
{
	/*StackOnly obj= StackOnly::creat();*/
	//虽然禁止了下面这个玩法,但是
	/*int* _ptr = new int;
	StackOnly* ptr = _ptr;*/
	/*StackOnly* ptr = new StackOnly(obj);*///这种情况也是能在堆上创建的!,所以解决它的办法就是去弄一个自己的类new
	//不管你调用什么函数,得先单例出来一个对象才可以!
	B::getInstance()->add("sort", "排序");
	B::getInstance()->add("interator", "迭代器");
	/*A::print();错误写法!*/
	B::getInstance()->print();
	//为了防止多个单例出现所以要禁掉拷贝构造!
}

单例模式细节(未完结)

相关推荐
WBluuue2 分钟前
Codeforces Good Bye 2025 Div1+2(ABCDE)
c++·算法
技术宅学长7 分钟前
关于CLS与mean_pooling的一些笔记
人工智能·pytorch·笔记·pycharm
bubiyoushang88814 分钟前
基于MATLAB的非线性有限元梁扭矩分析实现
开发语言·matlab
数据轨迹00120 分钟前
CVPR DarkIR:低光图像增强与去模糊一体化
经验分享·笔记·facebook·oneapi·twitter
No0d1es21 分钟前
2025年12月 GESP CCF编程能力等级认证Python二级真题
开发语言·python·青少年编程·gesp·ccf
工程师00726 分钟前
C#中的CIL(公共中间语言)
开发语言·c#·中间语言cil
资生算法程序员_畅想家_剑魔29 分钟前
Java常见技术分享-29-Jackson JSON处理类详解
java·开发语言·json
论迹31 分钟前
【多线程】-- JUC的常见类
java·开发语言·性能优化·多线程·juc
青春不败 177-3266-052035 分钟前
python语言生物信息多组学大数据深度挖掘与论文整理技巧
开发语言·python·生物信息·多组学·高通量测序
豆沙沙包?35 分钟前
2026年--Lc332-649. Dota2 参议院(队列)--java版
java·开发语言