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

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

时间2025-09-18 01:47:22分类IT科技浏览5467
导读:原文链接: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
自动驾驶仿真测试平台下载(介绍一款开源的自动驾驶仿真模拟器-Carla) 网站seo快速(提升网站排名的秘密武器:好用的SEO工具推荐)