拷贝构造函数 深拷贝 浅拷贝

 拷贝构造函数调用的三种形式

1.一个对象作为函数参数,以值传递的方式传入函数体;
2.一个对象作为函数返回值,以值传递的方式从函数返回;
3.一个对象用于给另外一个对象进行初始化(常称为复制初始化)。

总结:当某对象是按值传递时(无论是作为函数参数,还是作为函数返回值),编译器都会先建立一个此对象的临时拷贝,而在建立该临时拷贝时就会调用类的拷贝构造函数。

 

浅拷贝:

用户没有自定义(显式的声明)一个拷贝构造函数,当以上三种情况时,C++编译器会默认产生一个拷贝构造函数,这个默认的拷贝构造函数就是浅拷贝(也成为浅拷贝)。

 

深拷贝:

若用户显式的声明一个拷贝构造函数,使得类的对象在复制过程中资源重新分配,这就叫做深拷贝。

 

类中有指针对象时,要实现深拷贝的原因:

拷贝构造函数构造了一个新的对象,并给新对象的私有成员赋上参数对象的私有成员的值,新构造的对象和参数对象地址是不一样的,所以如果该类中有一个私有成员是指向堆中的某一块内存(也就是私有成员为指针时),如果仅仅进行浅拷贝,就会出现多个指针指向堆中的同一块内存,如果那块内存被释放了,其他指针也就指向了一块被释放的内存,也就变成了野指针,会造成系统的崩溃。如果采用深拷贝,每一次拷贝,都会开辟新的内存供对象其值,不会出现多个指针指向堆中的同一块内存的情况。

 

= 运算符必须实现深拷贝

#ifndef _STRING_H_
#define _STRING_H_
 
#include <iostream>
using namespace std;
 
class String
{
public:
    String();
    ~String();
    String(char *str);
    void display();
    //String(const String& other);
    String& operator=(constString& other);
private:
    char *str_;
};
 
#endif
 


#include "String.h"
 
String::String ()
{
    cout<< "construct test" <<endl;
    str_ = new char('\0');
}
 
String::~String ()
{
    cout<< "destroy construct test"<< endl;
    delete [] str_;
}
 
String::String (char*str)
{
    cout<< "default construct test"<< endl;
    int len = strlen(str) + 1;
    str_ = new char[len];
    memset(str_,0,len);
    strcpy(str_,str);
}
 
void String::display ()
{
    cout<< str_ << endl;
}
#if 0
String::String(constString& other)
{
    int len = strlen(other.str_ ) + 1;
    str_ = new char [len];
    memset(str_,0,len);
    strcpy(str_,other.str_);
}
#endif
String& String::operator=(const String& other)         = 运算符重载,实现深拷贝
{
    if(this ==&other)     //入口参数检查,判断s2是否是本身
    {
        return *this;
    }
    int len = strlen(other.str_ ) + 1;
    delete [] str_;
    str_ = new char[len];
    memset(str_,0,len);
    strcpy(str_,other.str_);
}

#include "String.h"
 
int main()
{
    String s;
    s = "hello";
    s.display();
 
    return 0;
}

若注释掉=运算符的重载,结果不正确


打开注释,结果正确

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值