剑指offer面试题1之赋值运算符函数

//要写一个赋值运算符函数,即重载赋值运算符,有两种形式:类成员函数和友元函数;我们这里用类成员函数的形式
#pragma once

class CMyString
{
public:
	//CMyString(void);//这个构造函数和CMyString(char* pdata = NULL)一定程度上重定义了,当定义
	                  //CMyString类型对象时,若都不传参,即用CMyString A;不知道调用哪一个了;
	                  //但CMyString A(NULL)就可以,但还是有警告多次定义构造函数!但当把=NULL去掉就
	                  //不会重定义了,因为去掉后,该构造函数需要传参才会被调用。
	~CMyString(void);
	//CMyString(char* pdata):m_pdata(pdata){}//这里声明和定义一起了(参数初始化列表)
	CMyString(char* pdata = NULL);//这里是默认m_pdata为NULL,即CMyString A;那A.m_pdata = NULL;
	CMyString(const CMyString& str);//拷贝构造函数,加const是为了不改变参数的状态
	                                //加&是为了避免调用拷贝构造函数时,由形参到实参调用拷贝构造函数
	                                //从而变成死循环!所以C++标准不允许拷贝构造函数传值参数
	CMyString& operator =(const CMyString& str);//重载赋值运算符函数,参数为引用,避免从形参到实参调用
	                                            //一次拷贝构造函数,这是无谓消耗,避免
	                                            //只有返回一个引用才能连续赋值
public:
	char* m_pdata;

};     

#include "StdAfx.h"
#include "CMyString.h"

//CMyString::CMyString(void)
//{
//}

CMyString::~CMyString(void)
{
}
CMyString::CMyString(const CMyString& str)
{
	this->m_pdata = str.m_pdata;
}
CMyString::CMyString(char* pdata)//这里不能加=NULL,否则会报重定义的错误
{
	this->m_pdata = pdata;
}
//CMyString& CMyString::operator =(const CMyString& str)//初级程序员做法,考虑点为:
//{                                              //1,判断传入的实例和当前实例是不是同一个实例,若是,直接返回  
//	                                           //2,是否释放实例自身的内存,若忘记,会出现内存泄露
//	                                           //3,传参是否为常量引用,为了高效,避免无谓消耗 
//	                                           //4,返回值是否为该类型的引用,为了可以连续赋值
//	if (this == &str)//若不判断,那么在释放内存后,传入参数也被释放了,再也找不到赋值内容了。                         
//	{
//		return *this;  
//	}
//	else                                           
//    {
//		delete[] m_pdata;//释放该实例的空间
//		m_pdata = NULL;//避免野指针
//		m_pdata = new char[strlen(str.m_pdata) + 1];
//		strcpy(m_pdata, str.m_pdata);
//		return *this;
//    }
//	                                         
//}                                              
//为什么说是初级程序员呢?
//因为没有考虑异常安全性原则,我们在分配内存之前就释放了实例的内存,那么若new char不成功,抛出异常
//那么m_pdata将是一个空指针,赋值没成功不止,还把原来的自己丢了。
//该进!!!!!
//第一种是:让一个局部指针指向m_pdata,再new一个空间,若成再释放这个局部变量指向的空间
//主要看第二种:
CMyString& CMyString::operator =(const CMyString& str)
{
	if (this != &str)
	{
		CMyString str_temp(str);
		char* ptemp = str_temp.m_pdata;
		str_temp.m_pdata = m_pdata;
		m_pdata = ptemp;//就是把局部变量m_pdata指向位置和该实例m_pdata指向位置互换
	}
	return *this;
}
//这好在哪呢?
//1,先创建一个临时实例,若不成功,抛出异常,不影响原来的自己,保证了异常安全性。
//2,若创建成功,str_temp是局部变量,作用域在if中,出了if就自动调用析构函数,而我们
//把str_temp.m_pdata和原来自己的m_pdata互换了,这时候析构的就是原来自己的空间了。

#include "stdafx.h"
#include <iostream>
#include <string>
#include <sstream>
#include "CMyString.h"
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
	//CMyString A(NULL);
	char *a = new char[10];
	string temp = "hello!!";
	stringstream ss;
	ss << temp;
	ss >> a;
	CMyString A(a);
	//测试用例1
	CMyString B = A;
	printf("%s\n", B);
	//测试用例2
	CMyString C;
	C = B = A;
	//cout << C.m_pdata;//m_pdata改成public可以
	printf("%s\n", C);
	//测试用例3
	B = B;
	printf("%s", B);
	system("pause");
	return 0;
}
//输出结果为:hello!!
//            hello!!
//            hello!!请按任意键继续...	   

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值