【C++深度剖析学习总结】 18 初始化列表的使用和对象的构造顺序

举报
CodeAllen 发表于 2021/10/29 23:36:32 2021/10/29
【摘要】 初始化列表的使用 作者 CodeAllen ,转载请注明出处 类中是否可以定义const成员? 可以 下面的类定义是否合法? 不合法 类中的const成员 #include <...

初始化列表的使用

作者 CodeAllen ,转载请注明出处

类中是否可以定义const成员?
可以

下面的类定义是否合法?
在这里插入图片描述
不合法

类中的const成员

#include <stdio.h>
class Test
{
private:
    const int ci;
public:
    Test() : ci(10)
    {
        //ci = 10;    //这里编译会出错的
    }
    int getCI()
    {
        return ci;
    }
};
int main()
{
    Test t;
   
    printf("t.ci = %d\n", t.getCI());
   
    return 0;
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

1.类成员的初始化
C++中提供了初始化列表对成员变量进行初始化
语法规则
在这里插入图片描述

注意事项

  • 成员的初始化顺序与成员的声明顺序相同 (容易出bug)
  • 成员的初始化顺序与初始化列表中的位置无关
  • 初始化列表先于构造函数的函数体执行

初始化列表的使用

class Test
{
private:
    value m2;
  value m3;
  value m1;
public:
Test() : m1(1),m2(2),m(3)
  {

  }
};

输出: 2 3 1  和声明顺序相同

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

2.类中的const成员

  • 类中的const成员会被分配空间的
  • 类中的const成员的本质是只读变量
  • 类中的const成员只能在初始化列表中指定初始值
  • 编译器无法直接得到const成员的初始值,因此无法进入符号表成为真正意义上的常量。

初始化与赋值不同

  • 初始化:对正在创建的对象进行初值设置
  • 赋值:对已经存在的对象进行值设置

小结
类中可以使用初始化列表对成员进行初始化
初始化列表先于构造函数体执行
类中可以定义const成员变量
const成员变量必须在初始化列表中指定初值
const成员变量为只读变量


对象的构造顺序

作者 CodeAllen ,转载请注明出处

1.对象的构造顺序一对于局部对象

  • 当程序执行流到达对象的定义语句时进行构造,对象定义->构造

下面程序中的对象构造顺序是什么?
在这里插入图片描述
局部对象的构造顺序

#include <stdio.h>
class Test
{
private:
    int mi;
public:
    Test(int i)
    {
        mi = i;
        printf("Test(int i): %d\n", mi);
    }
    Test(const Test& obj)
    {
        mi = obj.mi;
        printf("Test(const Test& obj): %d\n", mi);
    }
};
int main()
{
    int i = 0;
    Test a1 = i; //Test(int i):0
       
    while( i < 3 )
    {
        Test a2 = ++i; //Test(int i):1,2,3
    }
  //goto End;    
    if( i < 4 )
    {
        Test a = a1; //Test(const Test& obj):0
    }
    else
    {
        Test a(100);
    }
//End: //此时不会输出最后一个输出结果
    return 0;
}

/*
运行结果
Test(int i): 0
Test(int i): 1
Test(int i): 2
Test(int i): 3
Test(const Test& obj): 0
*/

  
 
  • 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
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47

2.对象的构造顺序二 对于堆对象

  • 当程序执行流到达new语句时创建对象
  • 使用new创建对象将自动触发构造函数的调用

下面程序中的对象构造顺序是什么?
在这里插入图片描述
堆对象的构造顺序

#include <stdio.h>
class Test
{
private:
    int mi;
public:
    Test(int i)
    {
        mi = i;
        printf("Test(int i): %d\n", mi);
    }
    Test(const Test& obj)
    {
        mi = obj.mi;
        printf("Test(const Test& obj): %d\n", mi);
    }
    int getMi()
    {
        return mi;
    }
};
int main()
{
    int i = 0;
    Test* a1 = new Test(i); // Test(int i): 0
       
    while( ++i < 10 )
        if( i % 2 )
            new Test(i); // Test(int i): 1, 3, 5, 7, 9
       
    if( i < 4 )
        new Test(*a1);
    else
        new Test(100); // Test(int i): 100
       
    return 0;
}

/*
运行结果
Test(int i): 0
Test(int i): 1
Test(int i): 3
Test(int i): 5
Test(int i): 7
Test(int i): 9
Test(int i): 100
*/

  
 
  • 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
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48

3.对象的构造顺序三 对于全局对象

  • 对象的构造顺序是不确定的 (当几个文件都定义了相同的全局变量)

  • 不同的编译器使用不同的规则确定构造顺序

  • 这就要求避免全局变量的互相依赖,所以尽量少用去全局变量

全局对象的构造顺序

#include "test.h"

Test t4("t4");  //

int main()
{
    Test t5("t5");
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

小结
局部对象的构造顺序依赖于程序的执行流
堆对象的构造顺序依赖于new的使用顺序
全局对象的构造顺序是不确定的

文章来源: allen5g.blog.csdn.net,作者:CodeAllen的博客,版权归原作者所有,如需转载,请联系作者。

原文链接:allen5g.blog.csdn.net/article/details/102758962

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。