C++学习(13)

#学习自用#

拷贝

拷贝就是将一个对象的数据或者内存复制到另一个地方,但是拷贝需要时间,如果只是想读取数据则应该避免没必要的拷贝。

浅拷贝

#include<iostream>
#include<string>
#include<memory>
using namespace std;
class entity
{
private:
	char* m_name;
	int m_size;
public:
	entity(char* s)
	{
		m_size=strlen(s);
		m_name=new char(m_size+1);
		memcpy(m_name,s,m_size+1);
	}
	~entity()
	{
		delete m_name;
	}
	friend std::ostream& operator<<(std::ostream& i,const entity& str);
};
std::ostream& operator<<(std::ostream& i,const entity& str)
{
	i<<str.m_name;
	return i;
}
void main()
{
	entity s("odd");
	entity i=s;
	cout<<s<<endl;
	cout<<i<<endl;
	cin.get();
}

entity i=s; 这个语句就是浅拷贝,使用的是C++中提供的默认拷贝函数 entity(const entity& other)

:m_name(other.m_name),m_size(other.m_size){},如果将拷贝函数删除(entity(const entity& other)=delete;),那么entity i=s;将会报错,这也是unique_ptr的原理。

这串代码可以正常运行,但在键入enter,退出程序时会报错,原因是s复制给i这条语句,i 和s是两个变量,位于不同的位置,在C++中执行的是将m_name和m_size的值复制到了i的内存地址处,两个实例其中的m_name指向了同一块地址,在程序结束时析构函数启动,导致同一个地址被delete了两次。(留个坑,个人认为实例 i 中的默认构造函数没有调用,如果有调用那么new重新分配内存的话就不会报错

这里代码其实有错误,new char(4)是分配一个字节的内存并将asc值为4的字符存入该地址,然后返回该地址,实际上应该是new char[4],这个才是分配四字节的内存,用错误的代码调试时虽然编译器没有报错,但是其实已经非法访问了。

深拷贝

利用默认拷贝函数的框架,我们可以构造自己的拷贝函数,实现m_name的内存在拷贝时重新分配,程序结束时就不会报错了,实现代码如下。

#include<iostream>
#include<string>
#include<memory>
using namespace std;
class entity
{
private:
	char* m_name;
	int m_size;
public:
	entity(char* s)
	{
		m_size=strlen(s);
		m_name=new char[m_size+1];
		memcpy(m_name,s,m_size+1);
	}
	entity(const entity& other)
		:m_size(other.m_size)
	{
		m_name=new char[m_size+1];
		memcpy(m_name,other.m_name,m_size+1);
	}
	~entity()
	{
		delete[] m_name;
	}
	friend std::ostream& operator<<(std::ostream& i,const entity& str);
};
std::ostream& operator<<(std::ostream& i,const entity& str)
{
	i<<str.m_name;
	return i;
}
void main()
{
	entity s("odd");
	entity i=s;
	cout<<s<<endl;
	cout<<i<<endl;
	cin.get();
}

函数传参(直接传变量)的时候也会发生复制,拖慢程序,将形参设置为引用变量就可以避免在传参时发生复制。传参要习惯用const!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值