android开发实战 mysql视频 Zookeeper安装 vue组件 list recursion download jboss grep ACE vue修改样式 jq点击事件 mysql数据库名称 mysql重新初始化 ipex接口 hbase端口 excel被保护怎么解除 mysql时间戳转换日期 mysql删除表 python功能 python调用方法 python基础练习 python传递参数 javadate stringjava javase教程 java写入文件 java教材 java系统时间 linux系统教程 网页游戏开发入门 EasyCHM dnf刷什么图赚钱 管理文件 3dmax2014下载 神魔辅助 视频旋转软件 ps怎么做漂亮艺术字 追评可以删除吗 ppt虚线怎么画
当前位置: 首页 > 学习教程  > 编程学习

C++深浅拷贝——实现String类

2021/1/9 2:04:45 文章标签: 深浅拷贝

浅拷贝:也称位拷贝,编译器只是直接将指针的值拷贝过来,结果多个对象共用同一块内存,当一个对象将这块内存释放掉之后,另一些对象不知道该块空间已经还给了系统,以为还有效,所以在对这段内存进行…


浅拷贝:也称位拷贝,编译器只是直接将指针的值拷贝过来,结果多个对象共用同一块内存,当一个对象将这块内存释放掉之后,另一些对象不知道该块空间已经还给了系统,以为还有效,所以在对这段内存进行操作的时候,发生了访问违规。

当类里面有指针对象时,拷贝构造和赋值运算符重载只进行值拷贝(浅拷贝),两个对象向同一块内存,对象销毁时该空间被释放了两次,因此程序崩溃!

深拷贝:为不同的指针对象各自开辟空间。


浅拷贝实现String类:(错误版)

class String
{
public:
	String(const char *str = NULL);
	String(const String &other);
	String& operator = (const String &other);
	~String();
private:
	char *m_data;
};

String::String(const char *str)
{
	if(str == NULL)
	{
		m_data = new char[1];
		*m_data = '\0';
	}
	else
	{
		int length = strlen(str);
		m_data = new char[length+1];
		strcpy(m_data, str);
	}
}

String::String(const String &other)
{
	strcpy(m_data, other.m_data);
}

String & String::operator =(const String &other)
{  
	//检查自赋值
	if(this == &other)
	{
		return *this;  
	}
	int length = strlen(other.m_data);
	m_data = new char[length+1];
	strcpy(m_data, other.m_data);

	//返回当前对象的引用
	return *this;
}

String::~String()
{
	delete[] m_data;
	m_data = NULL;
}




int main()
{
	String s;
	String s1 = "1111";
	String s4 = "33333";
	String s5 = "444444";
	String s6 = "666";
	String s2(s1);
	String s3 = "22222";
	String s7;
	String s8("hello world!");

	s1 = s3;


	system("pause");
	return 0;
}

拷贝构造函数:


赋值运算符的重载:

运行结果:




深拷贝:(普通版)

class String
{
public:
	String(const char *str = NULL);
	String(const String &other);
	String& operator = (const String &other);
	~String();
private:
	char *m_data;
};

String::String(const char *str)
{
	if(str == NULL)
	{
		m_data = new char[1];
		*m_data = '\0';
	}
	else
	{
		int length = strlen(str);
		m_data = new char[length+1];
		strcpy(m_data, str);
	}
}

String::String(const String &other)
{
	int length = strlen(other.m_data);
	m_data = new char[length+1];
	strcpy(m_data, other.m_data);
}

String & String::operator =(const String &other)
{  
	检查自赋值
	if(this == &other)
	{
		return *this;  
	}

	释放原有的内存资源
	delete[] m_data;

	分配新的内存资源,并复制内容
	int length = strlen(other.m_data);
	m_data = new char[length+1];
	strcpy(m_data, other.m_data);

	返回当前对象的引用
	return *this;
}

String::~String()
{
	delete[] m_data;
	m_data = NULL;
}




int main()
{
	String s;
	String s1 = "1111";
	String s4 = "33333";
	String s5 = "444444";
	String s6 = "666";
	String s2(s1);
	String s3 = "22222";
	String s7;
	String s8("hello world!");

	s1 = s3;


	system("pause");
	return 0;
}
浅拷贝:(引用计数版)

//浅拷贝:引用计数版
class String
{
public:
	String(char *pStr = "")
		:_pCount(new int(1))
	{
		if(NULL == *pStr)
		{
			pStr = new char[1];
			*pStr = '\0';
		}
		else
		{
			_pStr = new char[strlen(pStr)+1];
			strcpy(_pStr,pStr);
		}
	}
	String(const String& s)
		:_pStr(s._pStr)
		,_pCount(s._pCount)
	{
		++(*_pCount);
	}
	String& operator = (const String& s)
	{
		if(--(*_pCount) == 0 && _pStr)
		{
			delete[] _pStr;
			delete _pCount;
		}
		_pStr = s._pStr;
		_pCount = s._pCount;
		++(*_pCount);

		return *this;
	}
	~String()
	{
		if(--(*_pCount) == 0)
		{
			delete[] _pStr;
			delete _pCount;
			_pStr = NULL;
			_pCount = NULL;
		}
	}

private:
	char* _pStr;
	int* _pCount;
};




本文链接: http://www.dtmao.cc/news_show_1100278.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?