C++ deep copy 深度拷贝

当类的成员变量存在指针类型时,如果采用赋值语句将一个该类对象赋给另外一个对象时,默认会采用浅拷贝,也即两个指针类型的成员变量指向同一个地址,这样当对象生命周期结束时会调用析构函数,释放相应的内存地址。但是由于浅拷贝,会导致释放发生两次,如此第二次释放发生时,因为已经被释放过一次,所以程序会奔溃。代码如下:

#include <iostream>
#include <string>


class String{
private:
	char* m_Buffer;
	unsigned int m_Size;
public:
	String(const char* string){
		m_Size = strlen(string);
		m_Buffer = new char[m_Size +1];
		memcpy(m_Buffer, string, m_Size+1);
	}

	~String(){
		delete[] m_Buffer;
	}

	friend std::ostream& operator<<(std::ostream& stream, const String& string);
};

std::ostream& operator<<(std::ostream& stream, const String& string){
	stream << string.m_Buffer;
	return stream;
}

void PrintString(const String& string){
	std::cout << string <<std::endl;
}

int main(){

	String string = "Luobaotai";
	String second = string;


	PrintString(string);
	PrintString(second);

	std::cin.get();
}

定义了一个String类,有一个指针类型的成员变量,复写了操作符 <<, 用于支持string打印。由于复写函数需要调用String类的成员变量,所以将其定义为该类的友元函数。最后定义一个功能函数PrintString,供main调用。

编译运行,会发生前述的奔溃。

为了解决这个问题,需要引入深度拷贝。即不再拷贝指针变量地址,而是将指针内容拷贝到一个新的内存地址,建立一个新的指针,如此实现了结偶,使得析构函数调用时不再发生上述错误,代码如下,主要添加了新的构造函数 String(const String& other):

#include <iostream>
#include <string>


class String{
private:
	char* m_Buffer;
	unsigned int m_Size;
public:
	String(const char* string){
		m_Size = strlen(string);
		m_Buffer = new char[m_Size +1];
		memcpy(m_Buffer, string, m_Size+1);
	}

	String(const String& other)
	: m_Size(other.m_Size){

		std::cout << "copy string" <<std::endl;

		m_Buffer = new char[m_Size +1];
		memcpy(m_Buffer, other.m_Buffer, m_Size +1);
	}

	~String(){
		delete[] m_Buffer;
	}

	friend std::ostream& operator<<(std::ostream& stream, const String& string);
};

std::ostream& operator<<(std::ostream& stream, const String& string){
	stream << string.m_Buffer;
	return stream;
}

void PrintString(const String& string){
	std::cout << string <<std::endl;
}

int main(){

	String string = "Luobaotai";
	String second = string;


	PrintString(string);
	PrintString(second);

	std::cin.get();
}

ps:PrintString(const String& string)函数参数设置要注意,如果不使用引用,会导致函数调用时多次没必要的拷贝,降低效率,所以一定要加上&符号,使用引用。另外如果不想改变入参对应的值,一定要加上const

  • 6
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值