C++封装

本文详细介绍了C++的封装特性,对比了C语言中struct和C++中struct及class的区别,强调了C++封装的优缺点。还探讨了构造器constructor的作用、分类及其定义,并阐述了拷贝构造器copy constructor的使用场景和深拷贝浅拷贝的概念。最后,讨论了析构器destructor在对象销毁时的重要性。

封装

功能:对外提供接口,屏蔽数据,对内开放数据
class封装本质:将数据和行为,绑定在一起然后通过对象来完成操作

1. C++封装是对C封装的扩展

C语言封装概念:通过结构体struct将多个类型打包成一体,形成新的类型。
缺点:新类型不包含对数据类的操作。所的有操作都是通过函数的方式。

C++扩展了C语言结构体struct功能,可以用struct封装类,但struct 中所有行为和属性都是public 的(默认)。
优点:对外提供接口,可以直接访问其内部数据。
缺点:没有达到信息隐蔽的功效。

C++的class 可以指定行为和属性的访问方式,默认为pirvate,即屏蔽内部数据,又对外开放接口。

引申

1.1 C和C++中struct区别

三点:
C语言中的struct不能有成员函数,C++可以有
C语言中的struct没有public、private、protected访问权限设定,C++可以有
C语言的struct没有继承关系,C++可以有

1.2 C++中struct和class区别

两点:
默认继承权限不同,class默认private,struct默认public
class可以定义模板参数,像typename,struct不能定义为模板参数

2. 构造器constructor

用途:
构造器是C++中用于初始化对象
分类:
默认构造default constructor
有参构造
拷贝构造copy constructor

MyString(const char *str);//构造
MyString(const MyString &obj);//拷贝构造
MyString();//默认构造
~MyString(void);//析构

定义:
构造器定义
class 类名
{
类名(形参)
构造体
}

MyString::MyString()//默认构造函数
{
    string_len = 0;
    m_data =new char[1];
    m_data [0]= '\0';
    string_num++;   
}

MyString::MyString(const char *str)//构造函数
{
    if(str == NULL)
    {
        m_data = new char[1];
        if(m_data != NULL)
        *m_data = '\0';
        string_len = 0;
    }
    else
    {
        //为对象的str字符串new一个传入字符串大小的char空间
        this->m_data = new char[strlen(str)+1];
        if(m_data != NULL)
        strcpy(this->m_data,str);
        this->string_len = strlen(str);
    }

    string_num++;

}

拷贝构造器定义
class 类名
{
类名(const 类名& another)
拷贝构造体
}

MyString::MyString(const MyString &obj)//拷贝构造函数
{
    string_len =obj.string_len;
    m_data = new char[string_len+1];
    strcpy(m_data,obj.m_data);
    string_num++;
}

规则:
构造器:
1 无返回值,与类名同
2构造器在对象创建时自动被调用(默认调用)
3构造器和普通成员函数都遵循重载规则
4默认无参空体,一经实现,默认不复存在。
拷贝构造器:
1 系统提供默认的拷贝构造器。一经实现,不复存在。
2 系统提供的时等位拷贝,也就是所谓的浅浅的拷贝。
3 要实现深拷贝,必须要自定义。
使用:
有参构造调用

cout<<"请输入字符串\n";
char* usestr = new char[128];
memset(usestr,0,128);
cin>>usestr;
//有参构造函数
MyString str1(usestr);//括号 隐式调用
MyString str2 = "hi";//等号
MyString str3 = MyString("你好");//构造器显示调用

动态分配内存

MyStirng *p = new MyString;
MyString *p = new MyString("explicitly");

3. 何时会调用拷贝构造

对象初始化同类对象+函数按值传递类对象+函数返回类对象
场景1:对象初始化同类对象

//调用拷贝构造函数call copy constructor 
//MyString(const MyStirng &)
MyString str6(str2);//括号
MyString str4 = str1;//等号
MyString str5 = MyString(str2);//拷贝构造显示调用
MysStirng *p = new MyString(str1);//动态分配内存

场景2:函数按值传递类对象
场景3:函数返回类对象

//成员函数重载+号运算符
const MyString MyString::operator+(const MyString &rop)const
{
    MyString ret;//1默认构造ret对象
    ret.string_len = string_len + rop.string_len;
    ret.m_data = new char[ret.string_len+1];
    strcpy(ret.m_data,m_data);
    strcat(ret.m_data,rop.m_data);
    return ret;
    //2调用拷贝构造函数复制ret给匿名对象 
    //3再调用析构函数析构ret对象 
    //4传出了匿名对象
}

引申:

3.1 C++自动提供了哪些成员函数

所谓自动提供就是程序员没有手动定义这些函数
默认构造函数、默认析构函数、默认拷贝构造函数、赋值运算符、地址运算符

3.2 深拷贝浅拷贝

浅拷贝:仅仅复制成员的值
默认拷贝构造函数带来的危害:
如果使用默认拷贝构造函数复制类对象(静态成员)不会出现影响
如果使用默认拷贝构造函数复制指向字符串的指针,由于仅仅复制指针的地址值,出现两个类对象的指针指向同一块堆内存的情况,当调用析构函数时,先析构副本对象的指针指向的堆内存块,再析构原对象的指针指向的堆内存,然而堆内存已经被释放,此时原对象的指针是个野指针,所以再次析构出现异常。
深拷贝:复制对象的指针指向的堆内存
程序员自己定义的拷贝构造函数要遵循深拷贝规则

MyString::MyString(const MyString &obj)//拷贝构造函数
{
    string_len =obj.string_len;
    m_data = new char[string_len+1];//new堆内存
    strcpy(m_data,obj.m_data);//复制指向的堆内存
    string_num++;
}

4. 析构器destructor

对象销毁时期:
1.栈对象离开其作用域
2.堆对象被手动delete
规则:
1 对象销毁时,自动调用。完成销毁的善后工作。
2 无返值,与类名同,无参。不可以重载默认参数。
3 系统提供默认空析构器,一经实现,不复存在。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值