C++ 特殊类设计

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

 //设计一个对象 只能在堆上创建对象
class A {
public:
	void destory()
	{
		delete this;
	}
private:~A()
{

}
};


//设计一个对象 只能在堆上创建对象
class B
{
public:
	//这个地方要用static的原因是先有鸡还是先有蛋的问题 
	// 还要禁用拷贝构造 不然还是可以在非堆地区创建对象
	static B* create()
	{
		return new B;
	}

private:
	//C++ 11 =delete
	//C++ 98 只声明不实现
	//B(const B&);
	B(const B&)  = delete;
	B() {}
};

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

// C c1 = C::Create();
 // C* c2 = new StackOnly(c1);
//new =operator new +构造 但是这个地方构造被封死了
//但是依然可以调用拷贝构造 但是拷贝构造不能被封死
//因为create函数是传值返回 要拷贝给临时变量
class C
{
	static C create()
	{
		C cc;
	    return cc;
	}

private:
	C() {}
	void* operator new(size_t size) = delete;
	void operator delete(void* p) = delete;
};

3.请设计一个类,不能被拷贝

直接把赋值重载和拷贝构造禁调就好了!!!


class D
{
	//D(const D&);
	D (const D&) = delete;
	//	D operator =(const D&);
	D operator =(const D&) = delete;
};

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

//设计一个不能被继承的类
//C++ 11
class E  final
{
	// ....
};




//设计一个不能被继承的类
//C++98
class NonInherit
{
public:
	static NonInherit GetInstance()
	{
		return NonInherit();
	}
private:
	NonInherit()
	{
	}
};

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

单例模式:
一个类只能创建一个对象,即单例模式,该模式可以保证系统中该类只有一个实例,并提供一个
访问它的全局访问点,该实例被所有程序模块共享
饿汉模式
就是说不管你将来用不用,程序启动时就创建一个唯一的
懒汉模式
如果单例对象构造十分耗时或者占用很多资源,比如加载插件啊, 初始化网络连接啊,读取
文件啊等等,而有可能该对象程序运行时不会用到,那么也要在程序一开始就进行初始化,
就会导致程序启动时非常的缓慢。 所以这种情况使用懒汉模式(延迟加载)更好。
// 饿汉模式:一开始(main函数之前)就创建单例对象
// 1、如果单例对象初始化内容很多,影响启动速度
// 2、如果两个单例类,互相有依赖关系。 
// 假设有A B两个单例类,要求A先创建,B再创建,B的初始化创建依赖A
// 定义命名空间hungry,用于封装单例类,避免命名冲突
namespace hungry
{
	class Singleton
	{
	public:
		// 2、提供获取单例对象的接口函数(全局访问点)
		// 静态成员函数:属于类本身,无需对象即可调用,保证全局可访问
		static Singleton& GetInstance()
		{
			return _sinst;  // 返回唯一实例的引用
		}

		// 普通成员函数:用于演示单例对象的功能扩展
		void func();

		// 向单例的字典中添加键值对
		void Add(const pair<string, string>& kv)
		{
			_dict[kv.first] = kv.second;  // 操作单例内部的数据
		}

		// 打印单例中存储的所有键值对
		void Print()
		{
			for (auto& e : _dict)
			{
				cout << e.first << ":" << e.second << endl;
			}
			cout << endl;
		}

	private:
		// 1、构造函数私有:禁止外部通过new创建对象
		// 保证只能在类内部创建实例
		Singleton()
		{
			// 此处可以添加初始化逻辑(如读取配置文件、连接数据库等)
			// 例如:_dict = LoadFromFile("config.txt");
		}

		// 3、防拷贝:禁止通过拷贝构造或赋值创建新实例
		// C++11特性:=delete表示禁用该函数
		Singleton(const Singleton& s) = delete;
		Singleton& operator=(const Singleton& s) = delete;

		// 单例存储的数据:示例为一个字典(键值对集合)
		// 实际场景中可替换为任意需要全局共享的数据(如配置信息、缓存等)
		map<string, string> _dict;

		// 4、定义静态单例对象:类内声明,类外初始化
		// 静态成员属于类本身,整个程序生命周期内只有一份
		static Singleton _sinst;
	};

	// 静态成员变量类外初始化:程序启动时自动创建,保证唯一实例
	Singleton Singleton::_sinst;

	// 普通成员函数的类外实现
	void Singleton::func()
	{
		// 可以直接操作单例内部的数据
		_dict["xxx"] = "1111";
	}
}
namespace lazy  // 命名空间lazy,封装懒汉式单例类
{
	class Singleton
	{
	public:
		// 2、提供获取单例对象的接口函数(全局访问点)
		static Singleton& GetInstance()
		{
			// 懒加载核心:第一次调用时才创建实例
			if (_psinst == nullptr)
			{
				// 首次调用时new一个实例(只执行一次)
				_psinst = new Singleton;
			}

			return *_psinst;  // 返回实例的引用
		}

		// 显式释放单例的接口(特殊场景使用)
		// 说明:单例通常不需要主动释放,进程结束时OS会回收资源
		static void DelInstance()
		{
			if (_psinst)  // 若实例存在,则释放
			{
				delete _psinst;
				_psinst = nullptr;  // 释放后置空,避免野指针
			}
		}

		// 向单例的字典中添加键值对
		void Add(const pair<string, string>& kv)
		{
			_dict[kv.first] = kv.second;
		}

		// 打印字典中的所有键值对
		void Print()
		{
			for (auto& e : _dict)
			{
				cout << e.first << ":" << e.second << endl;
			}
			cout << endl;
		}

		// 内部嵌套类:用于自动释放单例(GC = Garbage Collection)
		class GC
		{
		public:
			// 析构函数:程序结束时自动调用,释放单例
			~GC()
			{
				lazy::Singleton::DelInstance();  // 调用释放接口
			}
		};

	private:
		// 1、构造函数私有:禁止外部创建实例
		Singleton()
		{
			// 此处可添加初始化逻辑(如从文件加载数据)
			// 例如:_dict = LoadConfig();
		}

		// 析构函数私有:只能通过DelInstance()释放
		~Singleton()
		{
			cout << "~Singleton()" << endl;  // 调试用:验证析构是否执行

			// 示例:程序结束时将字典数据持久化到文件
			FILE* fin = fopen("map.txt", "w");  // 打开文件(若不存在则创建)
			if (fin)  // 防止文件打开失败
			{
				for (auto& e : _dict)  // 遍历字典,写入键值对
				{
					fputs(e.first.c_str(), fin);  // 写键
					fputs(":", fin);              // 分隔符
					fputs(e.second.c_str(), fin); // 写值
					fputs("\n", fin);             // 换行
				}
				fclose(fin);  // 关闭文件
			}
		}

		// 3、防拷贝:禁止通过拷贝构造或赋值创建新实例
		Singleton(const Singleton& s) = delete;         // 禁用拷贝构造
		Singleton& operator=(const Singleton& s) = delete;  // 禁用赋值运算符

		// 单例存储的数据:示例为一个字典(键值对集合)
		// 实际场景可替换为配置信息、缓存、日志器等全局共享数据
		map<string, string> _dict;

		// 4、静态指针:指向单例实例(类内声明)
		// 初始值为nullptr,首次调用GetInstance()时被赋值
		static Singleton* _psinst;

		// 静态GC对象:用于程序结束时自动触发析构
		// 说明:静态对象的生命周期与程序一致,析构在main函数结束后执行
		static GC _gc;
	};

	// 静态成员变量类外初始化
	Singleton* Singleton::_psinst = nullptr;  // 指针初始化为nullptr(未创建实例)
	Singleton::GC Singleton::_gc;             // GC对象初始化(触发其默认构造)
}

//class GC
//{
//public:
//	~GC()
//	{
//		lazy::Singleton::DelInstance();
//	}
//};
//
//GC gc;

int main()
{
	//Singleton s1;
	//Singleton s2;

	cout << &lazy::Singleton::GetInstance() << endl;
	cout << &lazy::Singleton::GetInstance() << endl;
	cout << &lazy::Singleton::GetInstance() << endl;

	//Singleton copy(Singleton::GetInstance());

	lazy::Singleton::GetInstance().Add({ "xxx", "111" });
	lazy::Singleton::GetInstance().Add({ "yyy", "222" });
	lazy::Singleton::GetInstance().Add({ "zzz", "333" });
	lazy::Singleton::GetInstance().Add({ "abc", "333" });

	lazy::Singleton::GetInstance().Print();

	//lazy::Singleton::DelInstance();

	lazy::Singleton::GetInstance().Add({ "abc", "444" });
	lazy::Singleton::GetInstance().Print();

	//lazy::Singleton::DelInstance();

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值