首页 > 其他分享 >维护一个对象只能通过new来创建,且要实现对象能够自动销毁的单例代码实现及扩展。

维护一个对象只能通过new来创建,且要实现对象能够自动销毁的单例代码实现及扩展。

时间:2024-06-08 13:33:37浏览次数:22  
标签:调用 函数 对象 单例 new annimal

结论:析构函数设为私有且在单例类的内部维护一个Chelper类。(如果是单例,还要将构造函数设为私有,如果是可以在全局有多个实例但是希望只能提供new创建,则构造必须公有且必须提供成员函数来调用delete this 来调用该对象的析构函数)。具体细节可看代码解释部分。

代码实现:

test.h

class annimal
{
public:
	static annimal* getinstance()//只能访问静态成员变量,故将m_instance声明为静态变量
	{
		if (m_instance == NULL) {//保证全局只有这一个对象
			m_instance = new annimal();
		}
		return m_instance;
	}

private:
    annimal() {
		cout << "annimal 构造" << endl;
	}
	~annimal() {
		cout << "annimal析构函数" << endl;
	}
	static void releseInstance() {
		if (m_instance != NULL) {
			annimal* tmp = m_instance;
			m_instance = NULL;
			delete tmp;
		}
	}
	class CHelper {
	public:
		CHelper() {
			annimal::getinstance();//加这行,表示在main之前构造,否则需要在main中调用getinstance才能new,这不太好。我们希望在main中调用getianstance 时走的是m_instance !=NULL returnm_instance 这代码,即不在main里面new.而是在main之前new 
			cout << "helper构造函数" << endl;
		}
		~CHelper() {
			cout << "helper析构" << endl;
			annimal::releseInstance();
		}
	};

	static annimal* m_instance;
	static CHelper m_helper;

};

test.cpp

annimal* annimal::m_instance = NULL;
annimal::CHelper annimal::m_helper;

main.cpp

annimal* pannimal= annimal::getinstance();

代码解释:

1.只能New来创建

        必须将析构函数设置为私有,对外提供静态成员函数getinstance和静态成员变量m_instance.并在cpp中定义(因为静态成员变量必须要在类外定义)。且这里的New不是在main函数里面new.

2.实现自动释放

        因为new出来的对象必须显示调用delete 操作符才能调用到该对象的析构函数,而要实现自动调用delete,必须只能在类内定义静态成员函数调用delete ,因为析构函数为私有,在类外不能调用delete.

        现在问题转化为怎么自动调用该函数,即releseInstance,实现方式就是在定义一个帮助类,帮助类析构时调用releseInstance函数。那么帮助类什么时候析构呢?我们可以用帮助类声明一个在全局数据区的对象,即   static CHelper m_helper ,且静态变量必须初始化->所以在cpp中,annimal::CHelper annimal::m_helper。

        通过上面的步骤,实现了单例类在main 函数之前构造,在main函数结束后析构(因为m_helper为全局的静态变量,程序结束时就自动调用到m_helper的析构函数,该析构函数调用带调用releseInstance自动释放单例对象)。

3.关于如何使用显示的New得到多个对象。(即在main中使用new annimal 而不是 getinstance 函数)

        上面代码通过getinstance 得到对象,我们并没有在main中显示调用new,那我要如果需要得到多个对象(即不是单例),但只能通过New来创建这些对象,我们应该怎么实现呢?显示调用new应该怎么写呢。

        1.在test.h添加成员函数destory并将构造函数设置为公有。

	 public:
	annimal() {
		cout << "annimal 构造" << endl;
	}
    void destory()
	{
		delete this;
	}

        2.在main.cpp中,使用new出来的对象必须显示调用destory函数,才能将ani对象析构,(且使用new必须将构造函数声明为共有的才能new)。且此时对象就不是一个单例对象了,在全局可以声明多个该类的实例。(即不是单例了,故单例模式必须将构造函数也声明为私有)

	annimal* ani=new annimal;
	ani->destory();
       

       

3.总结

       1. 如果全局只需要一个实例对象,且要实现自动管理资源和释放。构造和析构都要私有,我们只需要调用getinstance 函数就可拿到这个实例。

        2.如果在Main中希望通过显示的New来创建对象且可以有多个对象被new,则必须将构造公有,析构私有。且必须实现成员函数destory来delete 对象,不然New出来的对象不会走析构代码。

        3.最后还要提供一些静态成员属性和方法来辅助实现。

       4.对于自动管理资源的单例对象 有什么好处呢?我们可以在项目中将上述的test.h和test.cpp添加到任何需要该实例的项目中,这样该项目就得到了一个自动管理单例对象的功能,我们只需用就行。且这个实例在main之前构造,main函数之后析构,此时一定时处于单线程的状态,不用关新代码冲突,资源竞争,加锁等问题。

标签:调用,函数,对象,单例,new,annimal
From: https://blog.csdn.net/qq_68245364/article/details/139544959

相关文章

  • Python中__面向对象__学习 (上)
    目录一、类和对象1.类的定义2.根据对象创建类二、构造和析构1.构造方法(1)不带参数的构造方法(2)带参数的构造方法2.析构方法三、重载1.定制对象的字符串形式(1)只重载__str__方法(2)只重载__repr__方法(3)重载__str__和__repr__方法2.运算符重载(1)加法运算重载(2)索引和分......
  • JAVA面向对象三大特征之继承
    目录1.继承概述2.继承的格式 3.继承的好处3.1继承的使用时机3.2注意4.继承中变量的访问特点5.总结1.继承概述在继承中我们可以把类分为两种一种是父类一种是子类,子类在继承父类后会获得父类中的属性和方法,在父类中定义过的属性和方法,子类中不需要再写一遍,同时子......
  • 模糊控制器实现对某个对象追踪输入
    MATLAB是一个十分便捷的软件,里面提供了许多集成的组件,本文利用simulink实现模糊控制器实现对某个对象追踪输入。这里的对象根据自己的需求可以修改,那么搭建一个闭环控制系统并不是难事儿,主要是对于模糊控制器参数的设置,我这里simulink的仿真图搭建如下:使用示波器观察了系统......
  • Spring家族框架——Spring3——IOC基于XML创建对象的方式
    ......
  • 一个全新newsxlr应用商店,极简就好
    前言写在前面,终于手机内存不再告罄了!一、什么是newsxlr应用商店?一个全新的应用商店——newsxlr快应用横空问世了!使用方便,不占内存,点开直接使用web手机页面,即可实现全部功能,不用再安装app。二、如何使用?1.即开即用使用任何一款浏览器(推荐使用newsxlr浏览器),输入网址htt......
  • 类和对象(二)(C++)
    初始化列表classDate{public:Date(intyear,intmonth,intday){_year=year;_month=month;_day=day;}private:int_year;int_month;int_day;};虽然上述构造函数调用之后,对象中已经有了一个初......
  • 07c/c++面向对象
    07C/c++零碎语法目录文章目录07C/c++零碎语法C1.封装2.继承3.多态C++4.1封装4.1.1封装的意义5.继承5.1继承的基本语法5.2继承方式5.3继承中的对象模型5.4继承中构造和析构顺序5.5继承同名成员处理方式5.6继承同名静态成员处理方式5.7菱形继承C1.封......
  • c++类与对象
    classBook{public:charname;intpages;voidprintpages();}voidprintpages(){std::cout<<"书的页数"<<endl;}在定义类的属性和方法时可以选择1.public:公有成员(在程序中类的外部是可访问的)。2.protected:受保护成员(在类的外部是不可访问的,甚......
  • c++的面对对象 的 虚函数
    #include<iostream>#include<string>classAnimal{public:virtualvoidmakeSound()=0;//纯虚函数,所有的动物都应该提供自己的叫声};classDog:publicAnimal{public:voidmakeSound()override{std::cout<<"Woof!"<&l......
  • 【C++修行之道】类和对象(五)日期类的实现、const成员、取地址及const和取地址操作符重
    目录一、日期类的实现Date.h 1.1GetMonthDay函数(获取某年某月的天数) 问:这个函数为什么不和其他的函数一样放在Date.cpp文件中实现呢?1.2CheckDate函数(检查日期有效性)、Print函数(打印日期)1.3实现日期类的逻辑运算符重载<运算符的重载 ==运算符重载其他运算符重载......