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

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

时间2025-06-19 17:16:14分类IT科技浏览3779
导读:原文链接: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
p153200怎么解决(P1352 没有上司的舞会+P1122 最大子树和(树形DP入门))