zoukankan      html  css  js  c++  java
  • 构造函数和初始化表、this指针与常函数、析构函数、拷贝构造与拷贝赋值(day05)

    十四 构造函数和初始化表
    ...
    5 初始化表
    1)语法形式
      class 类名{
         类名(形参表):成员变量1(初值),...{}
      };
    2)必须要使用初始化表的场景
    --》如果有类 类型的成员变量,而该类又没有无参构造函数,则必须通过初始化表来初始化该成员变量。
    --》类中包含"const"和“引用”成员变量,必须在初始化表中显式的初始化。
    注:成员变量的初始化顺序由声明顺序决定,而与初始化表的顺序无关。
    
    练习:使用初始化表为电子时钟类增加计时器功能。
    如果使用日历时间初始化时钟对象,表现为时钟功能。
    如果以无参的方式构造时钟对象,通过构造函数的初始化表将时分秒初始化为0:0:0,表现为计时器功能。
    
    
    十五 this指针与常函数
    1 this指针
    1)类的成员函数和构造函数中都有一个隐藏的类 类型指针参数,名为this.
    --》对于普通的成员函数,this指针就是指向调用该函数的对象。
    --》对于构造函数,this指针指向正在被创建的对象
    
    2)需要显式使用this的场景
    --》区分作用域
    --》从成员函数返回调用对象的自身(返回自引用)
    --》从类的内部销毁对象自身
    
    2 常成员函数(常函数)
    1)在一个普通成员函数后面加上const 关键字,这个成员函数就称为常函数。
      返回类型 函数名(形参表) const {函数体}
    2)常函数中的this指针是一个常指针,不能在常函数中修改成员变量的值。
    注:被mutable关键字修饰的成员变量可以在常函数中被修改。
    3)非 常对象既可以调用常函数也可以调用非 常函数,但是常对象只能调用常函数,不能调用非 常函数。
    4)函数名和形参表相同的成员函数,其常版本和非常版本可以构成重载关系,常对象调用常版本,非常对象调用非常版本。
    
    -------------
    十六 析构函数(Destructor)
    1 语法形式
    class 类名{
    public:
       ~类名(void){//清理对象在创建分配的动态资源}
    };
    1)函数名必须是"~类名"
    2)没有返回类型,也没有参数,不能被重载。
    3)主要负责清理对象在创建分配的动态资源。
    
    2 当对象被销毁时,析构函数将自动被执行
    1)栈对象当其离开作用域时,其析构函数被作用域终止的右花括号"{"调用。
    2)堆对象的析构函数被delete运算符调用。
    
    3 如果一个类没有显式定义析构函数,那么编译器会为该类提供一个缺省的析构函数;
    -->对基本类型的成员变量什么也不做
    -->对类类型的成员变量,会调用相应的析构函数
    
    4 对象的创建和销毁过程
    1)对象的创建
     --》分配内存
     --》构造成员子对象
     --》执行构造函数代码
    2)对象的销毁
     --》执行析构函数代码
     --》析构成员子对象
     --》释放内存
    ================================
    十七 拷贝构造和拷贝赋值
    1 浅拷贝和深拷贝
    1)如果一个类中包含指针形式的成员变量,缺省的拷贝构造函数只是复制了指针变量的本身,而没有复制指针所指向的内容,这种拷贝方式称为浅拷贝。
    2)浅拷贝将导致不同对象之间的数据共享,如果数据存放在堆区,可能会在析构时引发"double free"异常,因此就需要自己定义一个支持复制指针指向的内容的拷贝构造函数,即深拷贝。
    
    练习:自定实现String类,支持深拷贝构造
    class String{
    public:
       //构造函数
       String(const char* str = ""):
          m_str(
              strcpy(new char[strlen(str)+1],str)){
       /*       
             m_str = new char[strlen(str)+1];
             strcpy(m_str,str);
       */       
       }
       //析构函数
       ~String(void){
             delete[] m_str;
             m_str = NULL;    
       }
       //深拷贝构造
    
       //提供访问接口函数
       const char* c_str(void)const{
               return m_str; 
       }
    private:
       char* m_str;
    };
    int main(void)
    {
       String s1("Hello");
       String s2 = s1;//拷贝构造
       cout << s1.c_str() << endl;//Hello
       cout << s2.c_str() << endl;//Hello
       return 0;        
    }

     

  • 相关阅读:
    python2.7打印中文乱码的问题解决
    Tesseract5.0训练字库,提高OCR特殊场景识别率(一)
    git比较重要但是又容易忘记的操作
    ntp局域网时间同步操作
    Flask使用原生sql语句
    Linux的tail命令查看文件
    使用gitlab的webhook进行前端自动部署
    通过queue实现前端的被动接收
    互动interactive与多行输出
    复习
  • 原文地址:https://www.cnblogs.com/Kernel001/p/7729650.html
Copyright © 2011-2022 走看看