C++ 构造函数 浅复制 深复制问题

面向对象

在讨论C++ 构造函数 和 析构函数之前,需要了解一下面向对象这一概念.C++作为面向对象的编程语言,充分展示了面向对象的思想.

在字典中,“对象”被定义为:存在的或可被感知存在的事物。 (Athing presented to or capable of being presented to the senses.) 换句话说,对象可以是任何事物。“面向”的定义是:“被指向或针对
(directed toward)” .通常它使得“面向对象”成为一个形容词.

面向对象:被指向或针对你能够想到的任何事物。 ( object
oriented : directed toward just about anything you can think of)

面向对象三要素:抽象、封装和信息隐藏

抽象 是根据需求,捕获与问题相关的事物,描述与问题求解相关的该事 物数据和行为,忽略那些不重要的内容,得到对应于该事物的软件对象

封装 是根据需求为对象的数据提供外部访问接口
信息隐藏 使得对象的状态得以保持,只允许通过接口去修改对象的状态

这里需要区别C++的三大基本特征(侵删)

构造函数:

  1. 根据初始式,类对象的不同初始化方式由不同的构造函数来提供:

类对象的默认初始化和值初始化使用默认构造函数来完成
类对象的直接/参数初始化使用普通的参数构造函数来完成。
类对象的复制初始化使用拷贝构造函数或**拷贝赋值函数(移动构造函数)**来完成

2.浅复制和深复制问题:
对类进行复制的时候按位复制,即把一个对象各数据成员的值原样复制到目标对象中。当类中涉及到指针类型数据成员的时候,往往就会产生指针悬挂问题

浅复制:

class String
{
public: 
    String(const char* cstr =0)                   
    {
	    m_data = cstr;
	}
private:
    char* m_data;
};
char* str1="hello";
char* str2="word";
String s1(s);     
String s2 = s1;   //1
String s3(str2);  
s3 = s1;          //2

情况1:
s2=s1执行的是浅复制,s1.m_data和s2.m_date指向的是同一个内存地址,如果在析构函数里面有对内存的释放。就会出现内存访问异常。因为一块内存空间会被释放两次!
情况2:
s3 = s1执行的同样是浅复制,s1.m_data和s3.m_date指向的是不光同一个内存地址,s3原先指向"word"的内存由于没有进行销毁,出现内存泄漏问题

深复制:
class String:

#ifndef STRING_H
#define STRING_H


class String
{
public:
    String();                                      //默认构造函数,如果在类定义时,未对构造函数进行重载,编译器将自动生成该函数
    String(const char* cstr =0);                   //参数构造函数              

    //三个特殊函数Big Three    
    String(const String& str);                     //拷贝构造函数
    String &operator=(const String& str);          //拷贝赋值函数
    ~String();                                     //析构函数
    char* get_c_str() const{return m_data; };      //成员函数
private:
    char* m_data;
};

#endif // STRING_H

String.cpp:

inline String::String(const char *cstr)
{
    if(cstr){
        m_data = new char[strlen(cstr)+1];
        strcpy(m_data,cstr);
    }else {
        //未制定初始值
        m_data=new char[1];
        *m_data='\0';
    }
}

inline String &String::operator=(const String &str)
{
    if(this == &str)  //检查自我赋值,不可缺少,否则会出错
        return *this;
    
    //1.先释放m_data指向的空间
    //2.为m_data申请需要的空间
    //3.将str的值拷贝m_data
    delete [] m_data;           
    m_data = new char[strlen(str.m_data)+1];
    strcpy(m_data,str.m_data);
    return *this;
}

inline String::~String()
{
    delete [] m_data;
}

main.cpp:

int main()
{
    String s1();
    String s2("Hello");
    
    String s3(s1);   
    cout << s3<<endl;
    
    s3 = s2;         
    cout<<s3<<endl;

    return 0;
}

深复制主要三步:

1.先释放m_data指向的空间
2.为m_data申请需要的空间
3.将str的值拷贝m_data

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值