• <bdo id='hqhqu58t'></bdo><ul id='mpuf8bll'></ul>
    1. <small id='svei2xxv'></small><noframes id='r1iyv7bf'>

      <tfoot id='z5cppt08'></tfoot>

        <i id='h28xzcfe'><tr id='m6hmho63'><dt id='8f0pg60a'><q id='zcc70j6m'><span id='66qtr0w8'><b id='c689mchk'><form id='i6h52vc7'><ins id='ir7i3a21'></ins><ul id='ppnv0tsh'></ul><sub id='b40avyaa'></sub></form><legend id='psxvfl7v'></legend><bdo id='z2nqh0so'><pre id='7vfteyx4'><center id='l07aryys'></center></pre></bdo></b><th id='ocp3lwbv'></th></span></q></dt></tr></i><div id='n5rvtewi'><tfoot id='m1s379di'></tfoot><dl id='2qnfydzr'><fieldset id='cr8wsepb'></fieldset></dl></div>
      1. <legend id='cn01x0v0'><style id='ydqvrait'><dir id='wftqz7s6'><q id='23i842tc'></q></dir></style></legend>
        欢迎来到入门教程网!

        C++

        当前位置:主页 > 软件编程 > C++ >

        &amp;lt;三&amp;gt;对象的浅拷贝和深拷贝问题

        来源:本站原创|时间:2023-04-02|栏目:C++|点击:

        先看示例代码

        点击查看代码
        #include <iostream>
         #include<cstring>
        using 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<<this->pName<<" "<<this->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<<"执行构造函数"<<endl;
            }
        
            //自定义拷贝构造函数
            Student2(const Student2 &_stu2){
        
                this->age=_stu2.age;    
                int len =strlen(_stu2.getPName())+1;
                char *newPName =new char[len];
                this->pName=newPName;
                strcpy(this->pName,_stu2.getPName());
                cout<<"执行拷贝构造函数"<<endl;
        
            }
        
            ~Student2(){
                if(this->pName!=nullptr){
                    delete[]this->pName;
                    this->pName=nullptr;
                }
            }
        
            void showStudent(){
        
                int *p=(int *)this->pName;
                cout<<this->pName<<" "<<this->age<<" pName Heap Address ="<<p<<endl;
        
            }
        
            const char * getPName() const{
                 return this->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<<"执行构造函数"<<endl;
            }
        
            //自定义拷贝构造函数
            Student3(const Student3 & _stu){
        
                this->age=_stu.age;    
                int len =strlen(_stu.getPName())+1;
                char *newPName =new char[len];
                this->pName=newPName;
                strcpy(this->pName,_stu.getPName());
                cout<<"执行拷贝构造函数"<<endl;
        
            }
        
            //自定义赋值函数
            Student3 & operator= (const Student3 & _stu){
        
                //防止自赋值
                if(this==&_stu){return *this;}
        
                //注意: 需要先释放当前的堆内存空间!!
                delete []this->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<<"执行赋值函数"<<endl;
                return *this;
            }
        
            ~Student3(){
                if(this->pName!=nullptr){
                    delete[]this->pName;
                    this->pName=nullptr;
                }
            }
        
            void showStudent(){
        
                int *p=(int *)this->pName;
                cout<<this->pName<<" "<<this->age<<" pName Heap Address ="<<p<<endl;
        
            }
        
            const char * getPName() const{
                 return this->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 <iostream>
        #include <cstring>
        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<<"执行构造函数, 堆内存空间地址"<<(int *)this->pchar <<endl;
        
             }
        
             //拷贝构造
             MyString(const MyString & myString){
              
                //重新分配内存空间 
                int len =myString.stringLen()+1;
                this->pchar=new char[len];
                strcpy(this->pchar,myString.pchar);  
                cout<<"执行拷贝构造函数, 新创建堆内存空间地址"<<(int *)this->pchar <<endl;
         
             }
        
             //赋值函数
             MyString & operator=(const MyString & myString){
        
                 //防止自赋值
                 if(this==&myString){return *this;}
                 //释放现有的堆内存空间
                 delete[]this->pchar;
                 this->pchar=nullptr;
        
                int len =myString.stringLen()+1;
        
                this->pchar=new char[len];
                strcpy(this->pchar,myString.pchar);
                
                cout<<"执行赋值函数, 新创建堆内存空间地址"<<(int *)this->pchar <<endl;
        
                return *this;
        
             }
        
             int stringLen() const {     
                 return strlen(this->pchar);
             }
            
             //析构
             ~MyString(){
                 delete [] this->pchar;
                 this->pchar=nullptr;
             }
        
             void printChar() const{      
                 cout<<this->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;
        }
        
        

        <i id='1buarxpi'><tr id='3gmoyauq'><dt id='580dxx3s'><q id='brj98rzc'><span id='6g7yyrhx'><b id='g5ga7rua'><form id='i0lhxr4i'><ins id='gls6oh32'></ins><ul id='u6xxjcj8'></ul><sub id='epf5kxwo'></sub></form><legend id='ftmzg1b5'></legend><bdo id='6hlo0ul7'><pre id='ao2xxioc'><center id='mbj9jxrt'></center></pre></bdo></b><th id='v8u2x1g8'></th></span></q></dt></tr></i><div id='5dmkjsl4'><tfoot id='essle16i'></tfoot><dl id='ly6l5xs5'><fieldset id='g0hap4ji'></fieldset></dl></div>

        1. <legend id='oq9a1mmd'><style id='t8yt5fn3'><dir id='sghpvbpy'><q id='qucesq0v'></q></dir></style></legend>
            <bdo id='ufijuyaa'></bdo><ul id='m4dlnpzc'></ul>

              <tfoot id='f0zo4vrc'></tfoot>

              <small id='bkuq2o05'></small><noframes id='drbxu2ba'>

                <tbody id='q51r4rho'></tbody>
                • 上一篇:&amp;lt;二&amp;gt;掌握构造函数和析构函数

                  栏    目:C++

                  下一篇:&amp;lt;四&amp;gt;构造函数初始化列表

                  本文标题:&amp;lt;三&amp;gt;对象的浅拷贝和深拷贝问题

                  本文地址:https://www.xiuzhanwang.com/a1/c++/17092.html

                  网页制作CMS教程网络编程软件编程脚本语言数据库服务器

                  如果侵犯了您的权利,请与我们联系,我们将在24小时内进行处理、任何非本站因素导致的法律后果,本站均不负任何责任。

                  联系QQ:835971066 | 邮箱:835971066#qq.com(#换成@)

                  Copyright © 2002-2020 脚本教程网 版权所有

                    1. <small id='y8sh634l'></small><noframes id='y8v1gbss'>

                      <legend id='48rkkizk'><style id='zbi2bi4y'><dir id='q0t5k4i9'><q id='rkq8vjzk'></q></dir></style></legend>
                        <bdo id='w68beefn'></bdo><ul id='eb6yeiw1'></ul>
                      <tfoot id='nmdxocn5'></tfoot>

                      <i id='aldiyd2m'><tr id='a4mfrjpj'><dt id='fw8jnyo9'><q id='agxt6nmr'><span id='qahmulyx'><b id='dbny4zp8'><form id='4p42r1ws'><ins id='b8s1fjjx'></ins><ul id='gxpcqwf4'></ul><sub id='80c167le'></sub></form><legend id='9p8av9cq'></legend><bdo id='4a15y0t1'><pre id='w6cpyrng'><center id='2e1m0yhp'></center></pre></bdo></b><th id='rz6i6ane'></th></span></q></dt></tr></i><div id='7053lgk0'><tfoot id='e8ipwhja'></tfoot><dl id='jel8vfjs'><fieldset id='larfgyv0'></fieldset></dl></div>