59.有哪些情况必须用到成员列表初始化?作用是什么?
59.有哪些情况必须用到成员列表初始化?作用是什么?
1.必须使用成员初始化的四种情况
① 当初始化一个引用成员时;
struct MyClass
{
const int mya;
int& myb;
MyClass(int a, int& b) :mya(a), myb(b) {}
~MyClass() {}
};
② 当初始化一个非静态的常量成员时;
int a = 1;
class MyClass
{
public:
const int mA;
MyClass():mA(a)// 在初始化列表初始化mA的值
{
}
};
③ 当调用一个基类的构造函数,而它拥有一组参数时;
#include<iostream>
#pragma warning(disable:4996)
using namespace std;
class BaseClass
{
public:
int basea;
int baseb;
public:
BaseClass(int ref1, int ref2): basea(ref1), baseb(ref2)
{
}
};
class DerivedClass : public BaseClass
{
public:
int derivedc;
public:
DerivedClass(int arg1, int arg2, int arg3) : derivedc(arg1), BaseClass(arg2, arg3) {} // 使用BaseClass的构造函数来初始化基类对象
};
int main()
{
int m = 5;
int n = 6;
int p = 7;
DerivedClass s(m, n, p);
cout << s.basea << endl;
cout << s.baseb << endl;
cout << s.derivedc << endl;
}
④ 当调用一个成员类的构造函数,而他拥有一组参数;
#include <iostream>
using namespace std;
class StuClass
{
public:
// 成员变量,存储了一个MemberClass对象
int studentNum;
string studentName;
int studentAge;
// 主类的构造函数,使用成员初始化列表来初始化成员变量member
StuClass(int stuNum, string stuName, int stuAge) : studentNum(stuNum), studentName(stuName), studentAge(stuAge)
{
}
};
int main()
{
// 创建一个MainClass对象,并传递参数5给MainClass的构造函数
StuClass obj(20211101, "悟空", 26);
// 输出成员变量member的值,可以看到已经被初始化为5
cout << "学号:" << obj.studentNum << ",姓名:" << obj.studentName << ",年龄:" << obj.studentAge << endl;
return 0;
}
⑤ 成员类型是没有默认构造函数的类。
派生类的构造函数必须调用基类的构造函数初始化基类的那一部分成员;如果基类没有提供显示初始化式,则编译器隐式使用成员类型的默认构造函数,若类没有默认构造函数,则编译器尝试使用默认构造函数将会失败。
则必须在派生类构造函数的初始化列表阶段显示调用
class A
{
public:
A(int x) //因为我们写了构造函数,所以这个类没有默认构造函数了
{
_a = x;
}
public:
int _a;
};
class Data
{
public:
Data(int year = 0, int month = 0, int day = 0) :a(0) //使用初始化列表初始化
{
_year = year;
_month = month;
_day = day;
}
private:
int _year;
int _month;
int _day;
A a; //创建一个类的对象
};
2.成员初始化列表做了什么
①初始化基类:如果类有一个基类,可以在成员初始化列表中使用基类的构造函数来初始化基类对象。
#include<iostream>
#include <stdio.h>
#include <stdlib.h>
#pragma warning(disable:4996)
using namespace std;
#include <iostream>
using namespace std;
// 基类
class BaseClass
{
public:
BaseClass(int a, int b)
{
x = a;
y = b;
}
void printBaseClass() {
cout << "Base class: (" << x << ", " << y << ")" << endl;
}
protected:
int x;
int y;
};
// 派生类
class DerivedClass : public BaseClass
{
public:
DerivedClass(int a, int b, int c) : BaseClass(a, b)
{
z = c;
}
void printDerivedClass()
{
cout << "Derived class: (" << x << ", " << y << ", " << z << ")" << endl;
}
private:
int z;
};
int main()
{
DerivedClass derivedObj(1, 2, 3);
derivedObj.printBaseClass();
derivedObj.printDerivedClass();
return 0;
}
② 初始化成员变量:对于每个成员变量,可以使用成员初始化列表来指定其初始值。成员初始化列表中的顺序与成员变量在类中声明的顺序一致。
#include<iostream>
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#pragma warning(disable:4996)
using namespace std;
class MyClass
{
public:
MyClass() : member1(0), member2("default"), member3(123) {} // 使用成员初始化列表初始化成员变量
void printMyClass()
{
cout << "Obj.member1 = " << this->member1 << ", "
<< "Obj.member2 = " << this->member2 << ", "
<< "Obj.member3 = " << this->member3 << endl;
}
private:
int member1;
std::string member2;
double member3;
};
int main()
{
MyClass Obj;
Obj.printMyClass();
return 0;
}
③默认参数:如果成员变量有一个默认参数,可以在成员初始化列表中使用默认参数来初始化成员变量。
class MyClass
{
public:
MyClass(int arg1, int arg2 = 0) : member1(arg1), member2(arg2) {} // 使用默认参数来初始化成员变量
private:
int member1;
int member2;
};
需要注意的是,如果类中没有明确定义构造函数,则编译器会生成一个默认构造函数。在这个默认构造函数中,成员初始化列表中的值将被忽略,而成员变量将被初始化为默认值。此外,在使用成员初始化列表时,需要确保列表中的类型与成员变量的类型匹配,否则将导致编译错误。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)