首页IT科技如何在构造函数中初始化成员变量(C++构造函数初始化列表注意的坑)

如何在构造函数中初始化成员变量(C++构造函数初始化列表注意的坑)

时间2025-08-02 07:59:52分类IT科技浏览4427
导读:原文链接:https://www.zhoubotong.site/post/87.html 之所以写这篇文章,是觉得里面有些细节如果不注意,很容易...

原文链接:https://www.zhoubotong.site/post/87.html

之所以写这篇文章               ,是觉得里面有些细节如果不注意                      ,很容易出错或踩坑       ,网上有很多教程对这块的描述部分存在错误              。希望下面的介绍能给大家带来帮助                      。

大家知道当我们需要初始化类中的成员变量时       ,除了可以直接在构造函数里面进行直接赋值                      ,还可以使用初始化列表的方式来对成员变量进行初始化        。

提到这里              ,顺便说下什么是构造函数初始化列表              。

C++初始化列表

语法

Contructor(type1 var1, type2 var2): m_var1(var1), m_var2(var2) { }

参数

属性 描述 type1 形参 var1 的类型                     。 var1 形参 var1        。 type2 形参 var2 的类型       。 var2 形参 var2                     。 m_var1 成员变量 m_var1               。 m_var2 成员变量 m_var2       。

说明

我们使用初始化列表的方式       ,用形参 var1 初始化了成员变量 m_var1                      ,用形参 var2 初始化了成员变量 m_var2                     。举个例子:

#include <iostream> using namespace std; class Student { private: char *m_name; int m_age; float m_score; public: Student(char *name, int age, float score); void show(); }; // 采用初始化列表 Student::Student(char *name, int age, float score) : m_name(name), m_age(age), m_score(score) { // TODO } void Student::show() { cout << m_name << " age is " << m_age << "score is " << m_score << endl; } int main() { Student stu((char *)"鸠摩智", 28, 5); stu.show(); Student *pstu = new Student((char *)"慕容复", 27, 86); // 使用指针对象 new 实例化 pstu->show(); return 0; }

上面的例子定义构造函数时并没有在函数体中对成员变量赋值              ,而是在函数首部与函数体之间添加了一个冒号:,后面紧跟m_name(name), m_age(age), m_score(score)语句                      ,

可以理解成相当于函数体内部的m_name = name; m_age = age; m_score = score;也是赋值的意思               。

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

下面重点说下需要注意的地方:

初始化列表可以用于全部成员变量               ,也可以只用于部分成员变量                     。什么意思?比如我们只对 m_name 使用初始化列表                     ,其他成员变量还是=赋值: // 采用初始化列表 Student::Student(char *name, int age, float score) : m_name(name) { // 只用于部分成员变量 m_age = age; m_score = score; }

输出结果是一样的                      。 注意!注意!注意!       ,成员变量的初始化顺序与初始化列表中列出的变量的顺序无关               ,它只与成员变量在类中声明的顺序有关。

请大家仔细看下面的代码: #include <iostream> using namespace std; class Student { private: int m_age; float m_score; public: Student(float s); void show(); }; Student::Student(float s) : m_score(s), m_age(m_score) {} //注意这里:我们将m_score放在了m_age的前面                      ,看起来是先给m_score赋值       ,再给m_age赋值(m_age=m_score)       ,其实不是的 void Student::show() { cout << m_age << ", " << m_score << endl; } int main() { Student stu(99); stu.show(); return 0; }

结论

所以成员变量的赋值顺序由它们在类中的声明顺序决定                      ,在 上面的Student 类中              ,我们先声明的 m_age       ,再声明的 m_score                      ,

给 m_age 赋值时              ,m_score 还未被初始化,所以输出的m_age的值是默认类型的0;给 m_age 赋值完成后才给m_score 赋值                      ,此时 m_score 的值才是99              。

如果大家对上面理解了                     ,我们再看下面的代码,大家可以猜下输出啥? #include <iostream> using namespace std; class Student { private: int m_age; float m_score; public: Student(float s); void show(); }; Student::Student(float s) : m_score(s), m_age(m_score) { m_age = m_score; m_score = s; } void Student::show() { cout << m_age << ", " << m_score << endl; } int main() { Student stu(99); stu.show(); return 0; }

输出:99, 99               ,大家请细品!写到最后再提下:构造函数初始化列表还有一个很重要的作用

                     ,那就是初始化 const 成员变量                      。

网上很多教程说初始化 const 成员变量的唯一方法就是使用初始化列表        。这是错误的       ,描述的不够严谨               ,为什么这样说                      ,我们来看网上很多教程的例子: #include <iostream> using namespace std; class Student { public: Student(string name, int age) { m_name = name; m_age = age; } void show(); private: const string m_name; int m_age; }; void Student::show() { cout << m_name << ", " << m_age << endl; } int main() { Student stu("鸠摩智", 28); stu.show(); Student stu1("慕容复", 27); stushow(); return 0; }

输出:

于是网上很多教程说只能使用初始化列表的方式       ,来进行初始化       ,现在                      ,按照网上的说法修改程序如下: #include <iostream> using namespace std; class Student { public: Student(string name, int age) : m_name(name), m_age(age) {} void show(); private: const string m_name; int m_age; }; void Student::show() { cout << m_name << ", " << m_age << endl; } int main() { Student stu("鸠摩智", 28); stu.show(); Student stu1("慕容复", 27); stushow(); return 0; }

这次在构造函数上面              ,使用了初始化列表的方式       ,初始化了 const 成员变量                      ,这次程序没有报错              ,因此,const 成员变量只可以使用初始化列表的方式进行初始化( 误人)              。

这个描述是错误的                      ,并不是const 成员变量只能使用初始化列表                     。在构造函数里面初始化赋值是没有任何问题的        。

针对上面的问题我们来改下代码       。注意这里只是改变了m_name的数据类型为指针型                     。 #include <iostream> using namespace std; class Student { public: Student(char *name, int age) { // 使用构造方法初始化赋值 m_name = name; m_age = age; } void show(); private: const char *m_name; // 注意这里是指针变量的常量 int m_age; }; void Student::show() { cout << m_name << ", " << m_age << endl; } int main() { Student stu((char *)"鸠摩智", 28); stu.show(); Student stu1((char *)"慕容复", 27); stushow(); return 0; }

所以类中对于const 修饰                     ,既可以使用初始化列表的方式赋值,也可以使用构造函数的方式赋值               。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
docker数据卷有什么用(一篇文章教你实战Docker容器数据卷) 外链的好处(网站外链平台)