C++ 深浅拷贝

深浅拷贝

浅拷贝存在的问题:如果类不提供拷贝构造和拷贝赋值编译器将提供默认的拷贝构造和拷贝赋值,而默认的拷贝构造和拷贝赋值函数,对于指针型成员变量都是只复制地址,而并不是复制地址指向的数据,这将导致浅拷贝问题。为了获得完整意义上的对象副本,必须自己定义拷贝构造和拷贝赋值,针对指针型成员变量做深拷贝

拷贝构造与拷贝赋值

1.相对于拷贝构造,拷贝赋值需要做更多的工作

	避免自赋值
	分配新资源
	拷贝新内容
	释放旧资源
	返回自引用

2.无论是拷贝构造还是拷贝赋值,其默认实现对任何类型的指针成员都是简单地复制地址,因此应尽量避免使用指针型成员变量
3.出于具体原因的考虑,确实无法实现完整意义上的拷贝构造和拷贝赋值,可将它们私有化,以防误用
4.如果为一个类提供了自定义的拷贝构造函数,就没有理由不提供相同逻辑的拷贝赋值运算符函数

#include <iostream>
#include <cstring>
using namespace std;

class String
{
public:
    String(const char* psz=""):m_psz(new char[strlen(psz)+1])
    {
        strcpy(m_psz,psz);
    }

    ~String(/*String* this*/)
    {
        delete[] this->m_psz;
        this->m_psz=NULL;
    }
#if 0
    String(const String& that)//默认拷贝构造函数,只复制了地址,没有复制地址指向的数据
    {
    }
#endif
    String(const String& that):m_psz(new char[strlen(that.m_psz)+1])//复制数据,不复制地址(深拷贝)
    {   
        strcpy(m_psz,that.m_psz);
    }   
#if 0
    String& operator=(const String& that)//浅拷贝
    {
        m_psz=that.m_psz;
        return *this;
    }
#endif
    String& operator=(const String& that)//深拷贝赋值函数
    {   
        if(this != &that)//防止自赋值
        {
            delete[] this->m_psz;
            this->m_psz=new char[strlen(that.m_psz)+1];
            strcpy(this->m_psz,that.m_psz);
        }
        return *this;
    }

    char*c_str() {return m_psz;}
    
private:
    char* m_psz;//指针成员
};

int main()
{
    String s1("hello");
    cout << "s1:"<<s1.c_str()<<",s1维护的堆内存首地址:" << (void*)s1.c_str() << endl;
    String s2=s1;
    cout << "s2:"<<s2.c_str()<<",s2维护的堆内存首地址:" << (void*)s2.c_str() << endl;
    String s3;
    s3=s2;
    cout << "s3:"<<s3.c_str()<<",s3维护的堆内存首地址:" << (void*)s3.c_str() << endl;
    return 0;
}

运行结果
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值