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

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扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版