类的this指针,构造函数、析构函数、拷贝构造函数(C++)

1.this指针

(一)对象存储模型

  • 我们都知道一个类中即有成员变量,又有成员函数,那么对象模型的存储方式是怎样的呢?
  • 我们可以先看一下C语言是如何做的?
struct Person 
{     
    char _name[20];     
    char _gender[3];    
    int  _age; 
}; 


void SetPersonInfo(Person* p, const char* name, con st char* gender, int age) 
{     
    strcpy(p->_name, name);    
    strcpy(p->_gender, gender);    
    p->_age = age; 
} 

void PrintPersonInfo(Person* p)
{    
     cout<<p->_name<<" "<<p->_gender<<" "<<p->_ag e<<endl; 
} 
  • 从上述代码中,我们可以看到,函数如果要操作类对象,必须将类对象的地址给进来,否则无法对实参对象进行修改
  • 在C++中也是按照C中这种类似的方式进行处理的,只不过成员函数这里的指针是隐藏的,指向了调用该函数的对象本身,这个隐藏的指针就是this指针
  • 所以对于类的存储方式,每个对象只保存数据信息,代码和数据分开进行存储,调用相关函数时通过对象本身的this指针指向相关函数即可

(二)this指针

  • this指针指向的是类实例化出的对象,所以this指针的类型是类类型* const
  • this指针只是指向对象,并不是对象本身的一部分,所以不影响sizeof的结果
  • this指针可以明确对象想要调用的函数,所以this指针作用域在类"成员函数”的内部
  • this指针是“类非静态成员函数”的第一个默认的隐含的参数,编译器会自动进行传递,不需要编写者显示传递
  • 只有类的菲静态成员函数可以使用this指针,其他任何函数都不可以使用

2.类的六个默认成员函数

(一)构造函数

  • 概念
  • 构造函数是一个特殊的成员函数,名字与类名相同,创建类类型对象时,由编 译器自动调用,在对象的生命周期内只调用一次,保证每个数据成员都有 一个合适的初始值
  • class Date
     { 
    public:     
        Date(int year, int month, int day)     
        {        
             _year = year;         
             _month = month;         
        _day = day;    
        } 
    private:     
        int _year;     
        int _month;    
        int _day;
     };
    
    int main() 
    {    
         Date d(2017, 12, 25);    
         return 0; 
    } 
    
  • 特性
  • 函数名与类名相同
  • 没有返回值,原因是构造函数具有隐式的返回值,该值由系统内部调用
  • 新对象被创建时,由编译器自动调用构造函数,而且在这个对象的生命周期内仅且调用一次
  • 构造函数也可以进行函数重载,实参决定了调用哪个构造函数
  • 无参构造函数和带有缺省值的构造函数都认为是缺省的构造函数,并 且缺省的构造函数只能有一个 
  • 有初始化列表(可以不用)
  • 注意:每个成员只能在初始化列表中出现一次; 初始化列表仅适用于初始化类的数据成员,这些成员的初始化顺序没有前后之分,初始化顺序其实是和数据成员在类中的定义顺序有关;尽量不要使用成员初始化成员,而且初始化顺序最好是和成员的定义顺序保持一致
  • 最好使用初始化列表进行初始化的成员有:1)引用成员变量   2)const成员变量    3)类类型成员(该类有非缺省的构造函数)
  • 如果没有显式定义时,编译器会合成一个默认的构造函数
  • 构造函数不能用const修饰 ,原因是构造函数有可能是要修改类的成员变量的,所以最好是非const类型最好
  • 构造函数不能为虚函数,这个原因后面博客中又说道
     
  • 作用
  • 构造并且初始化对象
  • 类型转化

对于单个参数构造函数,可以将其接受参数转化成类类型对象。用 explicit修饰构造函数,抑制由构造函数定义的隐式转换,explicit 关键字位于类内部的构造函数的声明上,在类的定义体外部的定义上不再重复

(二)拷贝构造函数

  • 概念
  • 只有单个形参,而且该形参是对本类类型对象的引用(常用const修饰),这 样的构造函数称为拷贝构造函数。
  • 拷贝构造函数是特殊的构造函数,创建 对象时使用已存在的同类对象来进行初始化,由编译器自动调用   
  • class Date 
    { 
    public:     
        Date(int year, int month, int day)         
            : _year(year)         
            , _month(month)         
            , _day(day)     
        {} 
    
    
        Date(const Date& d)         
            : _year(d._year)         
            , _month(d._month)         
            , _day(day)     
       {} 
    private:    
        int _year;     
        int _month;     
        int _day; 
    }; 
    
    int main() 
    {    
         Date d1(2017, 12, 25);     
         Date d2(d1); 
    } 
    

     

  • 特征
  • 构造函数的重载,构造函数的性质拷贝构造函数均满足 
  • 参数必须使用类类型对象引用传递,原因是传值会无休止下去调用拷贝构造函数创建临时对象
  • 如果没有显式定义,系统会自动合成一个默认的拷贝构造函数。默认 的拷贝构造函数会依次拷贝类的数据成员完成初始化
     
  • 使用场景
  • 对象实例化对象
  • 作为函数参数
  • 作为函数返回值
     

(三)析构函数

  • 概念
  • 析构函数:与构造函数功能相反,在对象被销毁时,由编译器自动调用,完成类 的一些资源清理和汕尾工作
  • class Array 
    { 
    public:     
        Array(int capacity = 10)         
            , _array(NULL)        
            , _capacity(capacity)         
            , _size(0)     
        {        
             _array = (int*)malloc(sizeof(int)*_capacity);     
        } 
    
        ~Array()    
        {        
             if(_array)         
             {             
                free(_array);            
                 _capacity = _size = 0;        
             } 
        }
    
     private:   
         int* _array;    
         size_t _size;     
         size_t _capacity; 
    }; 
  • 特性
  • 析构函数在类名(即构造函数名)加上字符~
  • 析构函数无参数无返回值
  • 一个类有且只有一个析构函数。若未显示定义,系统会自动生成缺省 的析构函数,所以析构函数不能进行重载
  • 对象生命周期结束时,C++编译系统系统自动调用析构函数 注意析构函数体内并不是删除对象,而是做一些清理工作
    ​​​​​​​
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值