page contents

C++入门,构造函数初始化列表

构造函数的一项重要功能是对成员变量进行初始化,为了...

构造函数的一项重要功能是对成员变量进行初始化,为了达到这个目的,可以在构造函数的函数体中对成员变量一一赋值,还可以采用初始化列表。

C++构造函数的初始化列表使得代码更加简洁,请看下面的例子:

  1. #include <iostream>

  2. using namespace std;

  3. class Student{

  4. private:

  5. char *m_name;

  6. int m_age;

  7. float m_score;

  8. public:

  9. Student(char *name, int age, float score);

  10. void show();

  11. };

  12. //采用初始化列表

  13. Student::Student(char *name, int age, float score): m_name(name), m_age(age), m_score(score){

  14. //TODO:

  15. }

  16. void Student::show(){

  17. cout<<m_name<<"的年龄是"<<m_age<<",成绩是"<<m_score<<endl;

  18. }

  19. int main(){

  20. Student stu("小明", 15, 92.5f);

  21. stu.show();

  22. Student *pstu = new Student("李华", 16, 96);

  23. pstu -> show();

  24. return 0;

  25. }

运行结果:
小明的年龄是15,成绩是92.5
李华的年龄是16,成绩是96

如本例所示,定义构造函数时并没有在函数体中对成员变量一一赋值,其函数体为空(当然也可以有其他语句),而是在函数首部与函数体之间添加了一个冒号:,后面紧跟m_name(name), m_age(age), m_score(score)语句,这个语句的意思相当于函数体内部的m_name = name; m_age = age; m_score = score;语句,也是赋值的意思。

使用构造函数初始化列表并没有效率上的优势,仅仅是书写方便,尤其是成员变量较多时,这种写法非常简单明了。


attachments-2021-03-hlpLlcvq60605f4dcab21.jpg


初始化列表可以用于全部成员变量,也可以只用于部分成员变量。下面的示例只对 m_name 使用初始化列表,其他成员变量还是一一赋值:

  1. Student::Student(char *name, int age, float score): m_name(name){

  2. m_age = age;

  3. m_score = score;

  4. }

注意,成员变量的初始化顺序与初始化列表中列出的变量的顺序无关,它只与成员变量在类中声明的顺序有关。请看代码:

  1. #include <iostream>

  2. using namespace std;

  3. class Demo{

  4. private:

  5. int m_a;

  6. int m_b;

  7. public:

  8. Demo(int b);

  9. void show();

  10. };

  11. Demo::Demo(int b): m_b(b), m_a(m_b){ }

  12. void Demo::show(){ cout<<m_a<<", "<<m_b<<endl; }

  13. int main(){

  14. Demo obj(100);

  15. obj.show();

  16. return 0;

  17. }

运行结果:
2130567168, 100

在初始化列表中,我们将 m_b 放在了 m_a 的前面,看起来是先给 m_b 赋值,再给 m_a 赋值,其实不然!成员变量的赋值顺序由它们在类中的声明顺序决定,在 Demo 类中,我们先声明的 m_a,再声明的 m_b,所以构造函数和下面的代码等价:

  1. Demo::Demo(int b): m_b(b), m_a(m_b){

  2. m_a = m_b;

  3. m_b = b;

  4. }

给 m_a 赋值时,m_b 还未被初始化,它的值是不确定的,所以输出的 m_a 的值是一个奇怪的数字;给 m_a 赋值完成后才给 m_b 赋值,此时 m_b 的值才是 100。obj 在栈上分配内存,成员变量的初始值是不确定的。


attachments-2021-03-HZSkEag760605f6f51d44.jpg


初始化 const 成员变量


构造函数初始化列表还有一个很重要的作用,那就是初始化 const 成员变量。初始化 const 成员变量的唯一方法就是使用初始化列表。例如 VS/VC 不支持变长数组(数组长度不能是变量),我们自己定义了一个 VLA 类,用于模拟变长数组,请看下面的代码:

  1. class VLA{

  2. private:

  3. const int m_len;

  4. int *m_arr;

  5. public:

  6. VLA(int len);

  7. };

  8. //必须使用初始化列表来初始化 m_len

  9. VLA::VLA(int len): m_len(len){

  10. m_arr = new int[len];

  11. }

VLA 类包含了两个成员变量,m_len 和 m_arr 指针,需要注意的是 m_len 加了 const 修饰,只能使用初始化列表的方式赋值,如果写作下面的形式是错误的:

  1. class VLA{

  2. private:

  3. const int m_len;

  4. int *m_arr;

  5. public:

  6. VLA(int len);

  7. };

  8. VLA::VLA(int len){

  9. m_len = len;

  10. m_arr = new int[len];

  11. }

attachments-2021-03-dDRFzDWT60605ecbd432e.jpg

  • 发表于 2021-03-28 18:51
  • 阅读 ( 720 )
  • 分类:C/C++开发

0 条评论

请先 登录 后评论
小柒
小柒

1470 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 1470 文章
  3. Pack 1135 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章