C++——浅拷贝和深拷贝

浅拷贝:可以理解为没有真正的开辟内存拷贝数据,而是与原对象指向同一块内存,所以在修改当前对象的时候原始对象也会随之改变。且若原始对象中有动态成员时,因为析构时两个对象各自析构一次,但析构同一块内存,所以会出错。
深拷贝:它会开辟一块新的与原始对象一样大的内存空间,将原始对象的字段全部拷贝过来。这样各自拥有自己的数据块,在析构时不会出问题。
具体实现代码如下:

#include <iostream>
#include <string.h>                                                                                                                                   
#include <stdlib.h>

using namespace std;

class String
{
    public:
        String(const char* str)
            :_str(new char[strlen(str)+1])//+1是给'\0'留空间
        {   
            strcpy(_str, str);//将'\0'也拷贝了
        }   

        //String(const String&s)
        //    :_str(s._str)
        //{}

        String(const String& s)//将s拷贝给this
            :_str(new char[strlen(s._str)+1])
        {   
            strcpy(_str, s._str);
        }   

        (1)浅拷贝
        //    //-》字符串的默认赋值函数实现的是浅拷贝
        //String& operator=(const String& s)
        //{ 
        //    if(this != &s)
        //    {
        //        _str = s._str;
        //    }
        //    return *this;
        //} 
        //(2)深拷贝
        String& operator=(const String& s)
        {
            if(this != &s)//若是自己给自己赋值,虽然内容不会变,但是地址会改变
            {
                char* tmp = new char[strlen(s._str)+1];
                strcpy(tmp, s._str);
                delete[] _str;
                _str = tmp;
            }
            return *this;
        }

        ~String()
        {
            if(_str)
            {
                delete[] _str;
                _str = NULL;
            }
        }

        char* c_str()
        {
            return _str;
        }

    private:
        char* _str;
};
int main()
{
    //(2)深拷贝
    String s1("hello");
    char* str1 = "hello";
    cout<<sizeof(s1)<<endl;
    cout<<sizeof(str1)<<endl;

    String s2(s1);
    cout<<"s1# "<<s1.c_str()<<endl;
    cout<<"s2# "<<s2.c_str()<<endl;

    String s3("world!!!!!!");
    s1 = s3;
    s1 = s1;
    cout<<"s1# "<<s1.c_str()<<endl;
    cout<<"s3# "<<s3.c_str()<<endl;

    (1)浅拷贝
    //String s1("hello");
    //String s2(s1);
    //cout<<"s1# "<<s1.c_str()<<endl;
    //cout<<"s2# "<<s2.c_str()<<endl;

    //String s3("world!!!!!!");
    //s1 = s3;
    //s1 = s1;
    //cout<<"s1# "<<s1.c_str()<<endl;
    //cout<<"s3# "<<s3.c_str()<<endl;
    return 0;
}                   

深拷贝也可以这么实现:

class String
{
    public:
        String(const char* str)
            :_str(new char[strlen(str)+1])
        {   
            strcpy(_str, str);
        }   

        //s2(s1)
        String(const String& s)
            :_str(NULL)
        {   
           String tmp(s._str);
           swap(_str, tmp._str);
        }   

        s1=s3
        //String& operator=(const String& s)
        //{ 
        //    if(this != &s)
        //    {
        //        String tmp(s._str);
        //        swap(_str, tmp._str);
        //    }
        //    return *this;
        //} 

        //s1=s3
        String& operator=(String s)
        {                                                                                                                                             
            swap(_str, s._str);
            return *this;
        }   

        ~String()
        {
            if(_str)
            {
                delete[] _str;
                _str = NULL;
            }
        }

        char* c_str()
        {
            return _str;
        }
    private:
        char* _str;
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值