复制与拷贝构造函数
浅拷贝与深拷贝
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];//这里这样写其实有问题,因为字符串需要在其原有长度的基础上加一个终止符的长度,即m_Size + 1,
//这样才能正常输出,否则会在字符串后面带上一堆随机乱码,
memcpy(m_Buffer, string, m_Size);
}
~String()
{
delete [] m_Buffer;
}
};
std::ostream& operator<<(std::ostream& stream, const String& string)
{
stream << string.m_Buffer;
return stream;
}
int main
{
String string = "sxr";
String string2 = string;//这样就是浅拷贝,如果想要进行深拷贝,就要重载构造函数,写一个拷贝构造函数
std::cout << string << std:endl;
std::cin.get();
}
浅拷贝,对于指针类型的成员,浅拷贝不会去到指针指向的内存去复制对应的内容,而是单纯的复制指针,如果一个类没有指针类型,没有对内存进行分配,一般浅拷贝就够用了,但是类中含有指针成员,存在动态内存分配的操作,如果还用浅拷贝,后果就是两个对象的对应指针成员是指向的是同一片内存上的东西,是联动的,同时在析构的时候这一片内存会被析构两边,导致程序崩溃,这时候为了要将指针指向的内存处的数据一同拷贝出来就需要使用深拷贝
深拷贝,在复制一个类的对象的时候不仅仅是复制指针,而是新建一块内存,把原来内存上的东西复制到新的内存空间上,这样得到的新的对象与原本的对象是相互独立的,互不影响的。
拷贝构造函数
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];//这里这样写其实有问题,因为字符串需要在其原有长度的基础上加一个终止符的长度,即m_Size + 1,
//这样才能正常输出,否则会在字符串后面带上一堆随机乱码,
memcpy(m_Buffer, string, m_Size);
}
String(const char& other): m_Size(other.m_Size)
{
m_Buffer = new char[m_Size + 1];
memcpy(m_Buffer, other.m_Buffer, m_Size + 1);
}//加入了拷贝构造函数,这样在拷贝类的对象的时候,构造函数就会选择调用这个
~String()
{
delete [] m_Buffer;
}
};
std::ostream& operator<<(std::ostream& stream, const String& string)
{
stream << string.m_Buffer;
return stream;
}
int main
{
String string = "sxr";
String string2 = string;//这样就是深拷贝,构造string2对象的时候就会调用拷贝构造函数
std::cout << string << std:endl;
std::cin.get();
}
另外,cherno在这期视频里提到,尽量总是用const引用来传递参数和对象,这样会省去复制所消耗的时间和资源