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;
}