先看示例代码

点击查看代码
#include  #includeusing namespace std;class Student{public:    Student(int _age , const char * _name)    {                  this->age=_age;         int len=strlen(_name)+1;         char *tep=new char[len];         this->pName=tep;         strcpy(this->pName,_name);    }    ~Student(){                delete[]this->pName;        this->pName=nullptr;           }    void showStudent(){        cout<pName<<" "<age<<endl;    } private:    int  age;    char *pName;  };int main(){   Student s1(20,"zhangsan");   s1.showStudent();   Student s2=s1;     s2.showStudent();   return 1;}

上面示例代码中,对象的默认拷贝方式是内存数据拷贝,如果对象占用了外部资源,那么就会出现问题了,这里的外部资源
就是在堆上申请的空间存放名字用,
s1,s2两个对象中的名字指针都是指向了同一块堆内存区域,在结束main函数的是,s2先析构,s2会析构调堆上的内存空间,
s1再析构,由于s1对象的pName 指针和s2对象的pName指针指向的是同一块堆内存区域,但是该区域内存已经被释放了,所以遇到了问题

鉴于上面的问题,我们引出了 浅拷贝,深拷贝的问题和解决方法.

Student s2=s1; 会调用拷贝构造函数(该拷贝构造函数可以是系统自动生成的,或者你自己定义一个拷贝构造函数)
系统自动生成的拷贝构造函数做的是内存数据拷贝,所以就出现了上面的问题.因此我们需要定义属于自己的拷贝构造函数

改造代码如下

点击查看代码
class Student2{public:    Student2(int _age , const char * _name)    {                 this->age=_age;         int len=strlen(_name)+1;         char *tep=new char[len];            this->pName=tep;         strcpy(this->pName,_name);         cout<<"执行构造函数"<age=_stu2.age;            int len =strlen(_stu2.getPName())+1;        char *newPName =new char[len];        this->pName=newPName;        strcpy(this->pName,_stu2.getPName());        cout<<"执行拷贝构造函数"<pName!=nullptr){            delete[]this->pName;            this->pName=nullptr;        }    }    void showStudent(){        int *p=(int *)this->pName;        cout<pName<<" "<age<<" pName Heap Address ="<<p<pName;    } private:    int  age;    char *pName;  };int main(){   Student2 s1(20,"zhangsan");      s1.showStudent();   Student2 s2=s1;   s2.showStudent();    return 1;}

上面的代码还存在一个问题如下,如果在main函数中是下面的代码

Student2 s1(20,”zhangsan”);

Student2 s2(30,”lisi”);

s2=s1;

在main函数结束的是同样会遇到问题,这个时候就引出 赋值函数,我们需要定义自己的赋值函数

在 s2=s1这一段代码其实是这样调用的
s2.operator=(s1)

在你不定义自己的赋值函数的时候,系统会帮我们生成一个赋值函数,该赋值函数的赋值方式就是内存的数值拷贝,这种方式
在Student对象,会有问题,所以我们需要向自定义拷贝构造一样,定义一个属于自己的赋值函数

代码如下

点击查看代码
class Student3{public:    Student3(int _age , const char * _name)    {                 this->age=_age;         int len=strlen(_name)+1;         char *tep=new char[len];            this->pName=tep;         strcpy(this->pName,_name);         cout<<"执行构造函数"<age=_stu.age;            int len =strlen(_stu.getPName())+1;        char *newPName =new char[len];        this->pName=newPName;        strcpy(this->pName,_stu.getPName());        cout<<"执行拷贝构造函数"<pName;        this->age=_stu.age;            int len =strlen(_stu.getPName())+1;        char *newPName =new char[len];        this->pName=newPName;        strcpy(this->pName,_stu.getPName());        cout<<"执行赋值函数"<pName!=nullptr){            delete[]this->pName;            this->pName=nullptr;        }    }    void showStudent(){        int *p=(int *)this->pName;        cout<pName<<" "<age<<" pName Heap Address ="<<p<pName;    } private:    int  age;    char *pName;  };int main(){   Student3 s3(20,"zhangsan");      s3.showStudent();   Student3 s4(30,"lisi");   s4=s3;      s4.showStudent();   return 1;}

运用深拷贝浅拷贝实现String 代码如下

点击查看代码
#include #include using namespace std;class MyString{public:     //构造函数     MyString(const char * src){        //创建空串        if(src==nullptr){            this->pchar=new char[1];            this->pchar[0]='\0';        }        else{            int len =strlen(src)+1;            this->pchar=new char[len];            strcpy(this->pchar,src);        }        cout<<"执行构造函数, 堆内存空间地址"<pchar <pchar=new char[len];        strcpy(this->pchar,myString.pchar);          cout<<"执行拷贝构造函数, 新创建堆内存空间地址"<pchar <pchar;         this->pchar=nullptr;        int len =myString.stringLen()+1;        this->pchar=new char[len];        strcpy(this->pchar,myString.pchar);                cout<<"执行赋值函数, 新创建堆内存空间地址"<pchar <pchar);     }         //析构     ~MyString(){         delete [] this->pchar;         this->pchar=nullptr;     }     void printChar() const{               cout<pchar<<endl;     }private:    char *pchar;   };int main(){    MyString s1("abcd");    s1.printChar();    MyString s2=s1;//执行拷贝构造    s2.printChar();    MyString s3("1234");    s3=s1;//执行赋值函数    s3.printChar();        return 1;}