设计类、单例模式

本文探讨了C++中如何设计类仅在堆或栈上创建对象,介绍了单例模式的两种实现——饿汉式和懒汉式,以及它们在不同场景下的优缺点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.请设计一个类,该类只能在堆上创建对象

    方法:将类的构造函数和拷贝构造函数声明为私有,防止别人调用拷贝在栈上生成对象

               提供一个静态的成员函数,在该静态成员函数中完成堆对象的创建

class heaponly
{
public:
	static heaponly*getheap()
	{
		return new heaponly;
	}
private:
	heaponly()    //构造私有
	{}
	heaponly(const heaponly&);  //拷贝构造私有
};
int main()
{
	heaponly* p1 = heaponly::getheap();
	//heaponly p2;
	//heaponly p3(*p1);
	return 0;
}

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

class stackonly
{
public:
	static stackonly getonly()
	{
		stackonly obj;
		return obj;
	}
	void print()
	{
		cout << "haha" << endl;
	}
private:       
	stackonly()    //构造函数私有,防止在外部用new创建对象
	{}             //拷贝构造就在栈上,所以拷贝构造不用私有
	//stackonly(const stackonly&) = delete;
};
int main()
{
	stackonly obj = stackonly::getonly();
	obj.print();
	//stackonly* p = new stackonly;
	return 0;
}

    另外还有一种方式,这种方式并不完全正确

    方法:只要将new的功能屏蔽掉就可以,屏蔽operator new

class stack
{
public:
	stack()
	{}
private:
	void* operator new(size_t size);
	void operator delete(void* p);
};
//stack s3;   在数据段
int main()
{
	stack s1;
	//stack s2 = new stack;
	return 0;
}

这段代码中  在全局区创建的S3对象,S3在数据段,并不在栈上

单例模式:

    一个类只能创建一个对象,即单例模式,该模式可以保证系统中该类只有一个实例,并提供一个访问它的

    全局访问点,该实例被所有程序模块共享

    例如:在某个服务器程序中该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后

               服务进程中的其他对象再通过这个单例对象获取这些配置信息,这种方式简化了在复杂环境下的配置管理

1.饿汉模式

    就是说不管你用不用,程序启动时就创建一个唯一的实例对象

    优点:简单明了,无需关注线程安全问题

    缺点:如果在一个大环境下使用了过多的饿汉单例,则会生产出过多的实例对象,无论你是否要使用他们

class Singleton
{
public:
	static Singleton* GetInstance()
	{
		return &m_instance;
	}
	
private:
	Singleton()
	{};
	Singleton(const Singleton&) = delete;
	Singleton& operator=(Singleton const&);

	static Singleton m_instance;
};
Singleton Singleton::m_instance;
int main()
{
	Singleton *p1 = Singleton::GetInstance();
	return 0;
}

懒汉模式:

    如果单例对象构造十分耗时或者占用很多资源,比如加载插件,读取文件...有可能该对象程序运行时用不到

    就要在程序一开始进行初始化,就会导致程序启动时非常缓慢,这种情况使用懒汉模式(延迟加载)更好

    优点:延时加载,用的时候才会产生对象

    缺点:需要保证同步,付出效率的代价。

class Singleton
{
public:
	static Singleton* Getstance()
	{
		//加锁
		if (m_pInstance == nullptr)
		{
			m_mtx.lock();
			if (m_pInstance == nullptr)
			{
				m_pInstance = new Singleton;
			}
			m_mtx.unlock();
		}
		return m_pInstance;
	}
	//实现一个内嵌垃圾回收类
	class CGarbo{
	public:
		~CGarbo(){
			if (m_pInstance)
				delete m_pInstance;
		}
	};
	//定义一个静态成员变量,程序结束时,系统会自动调用它的析构函数从而释放单例对象
	static CGarbo Garbo;
private:
	Singleton(){};
	Singleton(const Singleton&) = delete;
	Singleton&operator=(const Singleton&) = delete;
	static Singleton* m_pInstance;
	static mutex m_mtx;
};
Singleton* Singleton::m_pInstance = nullptr;//单例对象指针
mutex Singleton::m_mtx;                     //互斥锁
Singleton::CGarbo Garbo;

   

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值