深圳网站建设引流获客工具
●浅拷贝:
顾名思义,浅拷贝只是将对象的值拷贝过来。
如果没有显示实现构造函数或是拷贝构造函数,那么编译器会默认以浅拷贝的方式自动生成。
造成的问题是,指针指向同一个地址,析构时析构两次将出错。
#define _CRT_SECURE_NO_WARNINGS#include<iostream>
#include<Windows.h>
#include<string.h>
using namespace std;class String
{
public:String():_str(new char[1]){_str[0] = '\0';}String(const char* str):_str(new char[strlen(str)+1]){strcpy(_str, str);}~String(){delete[] _str;}
private:char* _str;
};void test1()
{String s1;String s2("hello");String S3(s2);}int main()
{test1();system("pause");return 0;
}
●深拷贝
传统写法符合我们的正常思路,先创建相同大小的空间,再把内容拷过去。
class String
{
public://构造String(const char* str = ""):_str(new char[strlen(str) + 1]){strcpy(_str, str);}//拷贝构造String(const String& s):_str(new char[strlen(s._str)+1]){strcpy(_str, s._str);}//重载等号//s1(this)=s2(s)String& operator=(const String& s){if (this != &s){//释放旧空间delete[] _str;//开辟新空间并拷贝s内容char* newstr = new char[strlen(s._str) + 1];strcpy(newstr, s._str);//this指向新空间_str = newstr;}return *this;}~String(){if(_str)delete[] _str;}
private:char* _str;
};
void test2()
{String s1;String s2("hello");String s3(s2);String s4 = s2;
}
int main()
{//test1();test2();system("pause");return 0;
}
●深拷贝的现代写法:
class String
{
public://构造String(const char* str = ""):_str(new char[strlen(str) + 1]){strcpy(_str, str);}//拷贝构造String(const String& s):_str(nullptr){//用s构造新的StringString tmp(s._str);//交换this和tmpswap(_str, tmp._str);}//重载=//s1=s2String& operator=(const String& s){if (this != &s){String tmp(s._str);swap(_str, tmp._str);}return *this;}/*String& operator=(String& s){swap(_str, s._str);return *this;}*/~String(){if (_str)delete[] _str;}
private:char* _str;
};
void test3()
{String s1;String s2("hello");String s3(s2);String s4 = s2; // String s4; s4=s2; 调用重载“=”的表达式
}
int main()
{//test1();//test2();test3();system("pause");return 0;
}