• C++之构造函数、缺省构造函数


    在这里插入图片描述

    1、构造函数

    1.1 特征:

    • 名称与类名相同
    • 无返回值
    • 可以包含多个版本(重载)

    1.2 (C++11)代理构造函数

    class Str{
      //这个就是代理构造函数,在执行时,先执行Str(3),再执行Str()
      //即先打印2,再打印1
      Str():Str(3{
        std::cout <<  "1" << std::endl;
      }
    
      Str(int value){
        std::cout <<  "2" << std::endl;
        x = value;
    }
    
    private:
       int x;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    2-初始化列表,是用来初始化对象的(不是赋值的),划重点(因为C++是考虑性能的一门语言,所以初始化和赋值是2个概念)

    为什么有初始化的概念?是为了提升软件速度。初始化可以为变量赋初始值,赋值是把一个变量拷贝给另一个变量,所以赋值不涉及内存的分配。所以如果先初始化,再赋值的效率 < 直接初始化赋值的效率。
    所以在构造函数时最好使用初始化列表,什么是初始化列表呢?如下

    class Str()
    {
       Str(int value, std::string a)
       //这个就是初始化列表
       :x(value)
       ,y(a)
       {
          //这个是赋值
          x = value;
       }
    
    private:
    int x;
    std::string y;
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    要注意的地方:

    • 一些情况下必须使用初始化列表(如类中包含引用成员)
    class Str()
    {
     Str(int& value){
      //引用初始化,注意传参要加&,不然引用的是形参的对象,形参销毁会有问题?
      :x(value)
    }
    
    private:
    int& x;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 注意元素的初始化顺序与其声明顺序相关,与初始化列表中的顺序无关,
      为什么?因为初始化列表中的顺序有多种,但是程序销毁时是有顺序的(即后构造,先销毁),所以也必须要规定程序的初始化顺序,所以要按照声明的顺序进行初始化。

    • 使用初始化列表覆盖类内成员初始化的行为
      什么意思?两个概念,一个是初始化列表,一个是类内成员初始化
      如下:

    class Str{
    
    Str(int value, std::string name)
    //初始化列表
    : x(value)
    , y(name)
    {
    
    }
    
    private:
      //类内成员初始化
      int x = 3;
      string y = "a";
    
    }
    
    
    int main()、
    {
       Str m(4,"b");
    
       //实际m内部的x=4 y = "b",这是因为初始化列表在内成员初始化之后执行。
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    3、缺省构造函数:不需要提供实际参数就可以调用的构造函数,这里注意一点,一但提供了有参的构造函数,缺省构造函数就失效了(因为系统此时认为,默认的构造函数可能会带来未知的安全隐患,所以就失效了)
    class Str()
    {
      //这个就是缺省构造函数
      Str()
      {
      }
      //这个也是缺省构造函数,因为3是默认的
      Str(int value = 3){
      
      }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 合成的缺省构造函数会使用缺省初始化来初始化数据成员,
      即缺省的构造函数在初始化数据成员时,每个成员会再次调用自己的缺省构造函数,如果没有,就会报错。
    • 调用缺省构造函数时避免most vexing parse

    意思是:

    class Str{
      
    private:
    
    int x;
    }
    
    int main()
    {
      Str m; //right
      //这里程序会认为下面是一个返回类型为Str的函数
      Str m(); //wrong 
      //所以
      Str m{}; //right
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    可以使用default关键字定义缺省构造函数

    class Str(
       Str() = default;
    
    )
    
    • 1
    • 2
    • 3
    • 4
  • 相关阅读:
    性能测试流程注意事项(亲身经历希望能帮助到你)
    Java21 + SpringBoot3整合Redis,使用Lettuce连接池,推荐连接池参数配置,封装Redis操作
    B46 - STM32太阳能充电智能心率监测骑行仪
    【剑指Offer】29.顺时针打印矩阵
    数据结构与算法之顺序表详解
    【2015年数据结构真题】
    计算机毕业设计选题推荐-船运物流管理系统-Java项目实战
    day40 设计模式、jdk8新特性
    uniapp 使用和引入 thorui
    【重磅】聚焦券商终端业务,博睿数据发布新一代券商终端核心业务体验可观测平台
  • 原文地址:https://blog.csdn.net/windxf/article/details/127400349