C++练习Day4 剑指offer 赋值运算函数 创建单例类

赋值运算符函数

下面我们将编写代码,为一个CMyString类型添加赋值运算函数

class CMystring{
public:
	CMyString(char* pData=nullptr);
	CMyString(const CMyString& str);
	~CMyString(void);
private:
	char* m_pData;
};

写代码时有几点要注意:
1.返回值的类型:由于要完成连续赋值操作,函数的返回值必须声明为该类型的引用,并在函数结束前返回实例自身的引用(*this)
2.将传入的参数声明为常数引用
3.释放实例自身已有的内存,若忘记在分配新内存之前释放自身已有的空间,程序将出现内存泄漏
4.判断传入的参数和当前实例是否为同一实例,若果是就直接返回,不进行赋值
根据上述要求,我们可以写出代码

CMyString& CMyString::operator=(const CMyString& str)
{
	if(this==&str)
	return *this;
	delete[] m_pData;
	m_pData=nullptr;
	m_pData=new char[strlen(str.m_pData)+1];
	strcpy(m_pData,str.m_pData);
	return *this;
};

然而更高级的工程师不会止步于此,显然我们还有更多的东西需要去考虑。仔细观察上面的程序代码,我们会发现一项严重影响程序安全性的问题:当我们释放实例自身的内存后,我们申请新的内存空间,这时可能会因为内存不足而抛出异常,导致m_pData是一个空指针
我们有两种解决方法
1.先用new分配新内容,再delete释放已有的内容
2.创建一个临时实例,再交换临时实例和原来的实例
针对第二个方案,写下如下代码:

CMyString& CMyString::Operator=(const CMyString& str)
{
	if(this!=&str)
	{
		CMyString strTemp(str);
		char* pTemp=strTemp.m_pData;
		strTemp.m_pData=m_pData;
		m_pData=pTemp;
	}
	return *this;
}

strTemp是一个局部变量,当其离开if时就出了变量的定义域,自动调用strTemp的析构函数,把strTemp.m_pData所指的内存——即实例之前的m_pData内存释放

设计一个类,我们只能生成该类的一个实例

当我们在程序中声明一个对象时,编译器调用构造函数,而调用通常来自外部,而不是class对象本身的调用
为了不让外部对象创建该类的实例,我们将该类的构造函数声明为private,这样就只能通过class内部创建对象实例,然而没有该类的实例,我们该如何访问class内部呢?
解决方案就是利用static公有成员,它独立于class对象而存在,而我们就可以利用这个公有成员函数访问该类内部
若我们再某static函数中创建了该class对象,并以引用或者指针形式将该对象返回(不能以该对象直接返回,主要是因为构造函数为私有函数,外部无法创建临时对象),这样我们就获得了该对象的使用权。
下面是单线程代码

class lazySingleton//懒汉模式,按需创建Singleton对象实例
{
private:
	Singleton()
	{
		cout<<"Singleton()"<<endl;
	}
	static Singleton* instance;
public:
	static Singleton* get_instance()
	{	
		if(instance==NULL)
		{
			instance=new Singleton();
		}
		return instance;
	}
	static Singleton* destroy()
	{
		delete instance;
		instance=NULL;
	}
};
Singleton* Singleton::instance=NULL;
int main()
{
	Singleon* sl= Singleon::get_Singleon();
	cout << sl<< endl;
	system("pause");
	return 0;
}

class eagerSingleton//饿汉模式,在类加载时就完成了初始化
{
private:
	Singleton()
	{
		cout<<"Singleton()"<<endl;
	}
	static Singleton* instance;
public:
	static Singleton* get_instance()
	{	
		return instance;
	}
	static Singleton* destroy()
	{
		delete instance;
		instance=NULL;
	}
};
Singleton* Singleton::instance=new Singleton();
int main()
{
	Singleon* sl= Singleon::get_Singleon();
	cout << sl<< endl;
	system("pause");
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值