你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

C++里面的初始化列表运用

[复制链接]
gaosmile 发布时间:2020-7-18 18:15
大家周末好,本次给大家分享的内容是C++里面的初始化列表运用,希望对大家有帮助。
一、引出列表的使用:
1、在介绍列表之前,我们先来看看使用const关键字来修饰类中的成员会有什么事情发生,下面是一段简单代码:
#include <stdio.h>

class Test{
private:
     const int a;
public:
     int getA()
     {
         return a;
     }

};
int main()
{
    return 0;
}

编译:
root@txp-virtual-machine:/home/txp/c++# g++ test.cpp
root@txp-virtual-machine:/home/txp/c++#

从编译结果来看,没毛病,完全和正常修饰一个成员一样;为了要显示这里的细节问题,我们来创建一个对象,进而调用类里面的方法来获取成员a的值:
#include <stdio.h>

class Test{
private:
     const int a;
public:
     int getA()
     {
         return a;
     }

};
int main()
{
    Test t;
    printf("the t.a is %d\n",t.getA());
    return 0;
}

编译:
root@txp-virtual-machine:/home/txp/c++# g++ test.cpp
test.cpp:3:7: error: uninitialized const member in ‘class Test’
test.cpp:5:16: note: ‘const int Test::a’ should be initialized
      const int a;

通过编译我们发现他报了一个错误,说成员a没有进行初始化;那么没有初始化,我们就给成员a一个值来进行初始化:
#include <stdio.h>

class Test{
private:
     const int a;
public:
     Test()
     {
        a=666;
     }
     int getA()
     {
         return a;
     }

};
int main()
{
    Test t;
    printf("the t.a is %d\n",t.getA());
    return 0;
}

我们是用了无参构造函数对a进行初始化(private里面的成员不能直接初始化,被保护住了,这个知识是基本常识哈),下面编译看看,会有啥现象发生:
root@txp-virtual-machine:/home/txp/c++# g++ test.cpp
test.cpp: In constructor ‘Test::Test()’:
test.cpp:7:6: error: uninitialized const member in ‘const int’ [-fpermissive]
      Test()
      ^~~~
test.cpp:5:16: note: ‘const int Test::a’ should be initialized
      const int a;
                ^
test.cpp:9:11: error: assignment of read-only member ‘Test::a’
         a=666;

和没有const关键字修饰的成员还不一样,上面说a还是要初始化,也就是我们在构造函数体里面对a进行进行初始赋值是行不通的哦,那该如何解决解决这个问题呢?答案来了,就是我们的初始化列表。
二、初始化列表“闪亮登场”:
1、首先我们先来看一下初始haul列表的书写格式:
ClassName::ClassName:
   m1(v1),m2(v1,v2),m3(v3)
  {
  
  }

从上面我们可以发现,初始化列表就是在构造函数名称后面且在构造函数体之间。同时这里我们也要注意初始化列表的使用原则:
(1)成员的初始化顺序与成员的声明顺序相同。
(2)成员的初始化顺序与初始化列表中的位置无关。
(3)初始化列表优先于构造函数的函数体执行。
我们接着上面那个初始的问题,现在我们使用初始化列表来看看啥情况:
#include <stdio.h>

class Test{
private:
     const int a;
public:
     Test():a(666)
     {
       // a=666;
     }
     int getA()
     {
         return a;
     }

};
int main()
{
    Test t;
    printf("the t.a is %d\n",t.getA());
    return 0;
}

编译:
root@txp-virtual-machine:/home/txp/c++# g++ test.cpp
root@txp-virtual-machine:/home/txp/c++# ls
a.out  test.cpp
root@txp-virtual-machine:/home/txp/c++# ./a.out
the t.a is 666

问题被完美解决,是不是心里很开心哈。接下来我们继续举一个上面规则里面说的初始化顺序问题:
#include <stdio.h>

class Value{
private:
        int b;
public:
        Value(int c)
        {
           printf("the c is %d\n",c);
           b=c;
        }
        int getB()
        {
          return b;
        }
};

class Test{
private:
        Value d1;
        Value d2;
        Value d3;
public:
        Test():d2(2),d1(1),d3(3)
        {
            printf("TXP \n");
        }

};

int main()
{
   Test t;

   return 0;
}

编译:
root@txp-virtual-machine:/home/txp/c++# g++ test.cpp
root@txp-virtual-machine:/home/txp/c++# ./a.out
the c is 1
the c is 2
the c is 3
TXP


从上面的输出结果我们可以初始化的顺序与成员的声明顺序有关,同时他也先于构造函数体的执行。
三、类中的const成员:
现在我们来总结一下在类中使用const关键字来修饰类中的属性时,这时的属性有啥特征:
(1)类中的const成员会被分配空间的。
(2)类中的const成员的本质是只读变量。
(3)类中的const成员只能再初始化列表中指定初始值
(4)编译器无法直接得到const成员的初始值,因此无法进入到符号表成为真正意义上的常量(也就是说这里的只读变量,我们还是可以通过一定的手段来改变其值的大小。)
下面我们来看一个例子:
#include <stdio.h>

class Value{
private:
        int b;
public:
        Value(int c)
        {
           printf("the c is %d\n",c);
           b=c;
        }
        int getB()
        {
           return b;
        }
};

class Test{
private:
        const int f;
        Value d1;
        Value d2;
        Value d3;
public:
        Test():d2(2),d1(1),d3(3),f(888)
        {
           printf("TXP\n");
        }
        int getF()
        {
           return f;
        }
        int setF(int i)
        {
           int *p = const_cast<int*>(&f);
               *p = i;
        }

};
int main()
{
   Test t;

   printf("the f is %d\n",t.getF());

   t.setF(666);

   printf("the f is %d\n",t.getF());
}

编译:
root@txp-virtual-machine:/home/txp/c++# g++ test.cpp
root@txp-virtual-machine:/home/txp/c++# ./a.out
the c is 1
the c is 2
the c is 3
TXP
the f is 888
the f is 666

通过上面的例子,我们的结论都得到了一一验证。
四、总结:
(1)类中可以使用初始化列表对成员进行初始化。
(2)初始化列表先于构造函数体执行。
(3)类中可以定义const成员变量。
(4)const成员变量必须在初始化列表中指定初值。
(5)const成员变量只为只读变量。
以上就是本次的学习分享。纯属个人学习c++的成长之旅。

收藏 评论1 发布时间:2020-7-18 18:15

举报

1个回答
likang1202 回答时间:2020-7-19 09:23:19
顶一下
mark.png

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版