信阳网站网站建设,wordpress 如何使用,seo技术入口,移动互联网开发技术期末试题一、初始化列表定义 初始化列表#xff1a;以一个冒号开始#xff0c;接着是一个以逗号分隔的数据成员列表#xff0c;每个成员变量后面跟一个放在括号中的初始值或表达式。 class Date
{
public:Date(int year, int month, int day): _year(year), _month(mont…一、初始化列表定义 初始化列表以一个冒号开始接着是一个以逗号分隔的数据成员列表每个成员变量后面跟一个放在括号中的初始值或表达式。 class Date
{
public:Date(int year, int month, int day): _year(year), _month(month)//初始化列表, _day(day){}
private:int _year;int _month;int _day;
}; 二、初始化列表内在作用的剖析 不知道大家有没有想过这样一个问题成员函数明明可以在函数内部对成员变量进行赋值那为什么还要搞出初始化列表这个东西呢这个时候就需要我们对初始化列表有一个更加深刻的理解了。 我们知道在一个类被设计出来的时候它里面定义的成员变量只是变量的声明没有为其分配空间。我们也知道类定义出一个对象是在主函数中定义的而创建出来的这个对象其中的成员变量其实是在初始化列表中定义的。那么假设我们创建出来的类的成员变量中含有引用类型或者是被const修饰时引用类型和const修饰的变量在定义时就必须为其赋初始值就像下面这个代码 如果我们定义的类内部的成员变量中含有引用类型或者是被const修饰而在成员函数体内部再对其赋初始值就相当于_ref和_n两个变量定义和赋初始值分离了但我们明确地知道引用类型或者是被const修饰的变量在定义时就必须为其赋初始值所以编译器会报未初始化的错误。上面图片中的代码还可以写的更明确一点就相当于下面这种形式 五个成员变量全部定义和赋初始值分开一般的内置类型是支持这种行为的。就像是这样
int main()
{int a;a 10;//可以int n;n a;//报错const int m;m 10;//报错return 0;
}
所以正确的方法应该是类内部的成员变量中含有引用类型或者是被const修饰时引用类型或者是被const修饰的成员变量必须用初始化列表赋初值定义时就赋初值。
class Date
{
private:int _year;int _month;int _day;int _ref;const int _n;public:Date(int year, int month, int day):_year(),_month(),_day(),_ref(month),_n(1){this-_year year;this-_month month;this-_day day;}
};
三、类中成员变量含有自定义类型的情况
很好理解自定义也必须使用初始化列表进行初始化如果自定义类型没有显示地调用初始化列表那么自定义类型就会去调用它的默认构造函数如果没有默认构造函数就会编译报错。
#include iostream
using namespace std;class A
{
private:int _a;public:A(int a 0){this-_a a;}
};class Date
{
private:int _year;int _month;int _day;A aa;int _ref;const int _n;public:Date(int year, int month, int day):_year() //aa没有显示地调用初始化列表会去调用它的默认构造函数, _month()//剩下的三个成员没有写出来定义但是它也会定义只是内置类型给的随机值, _day() //自定义类型会去调用它的默认构造函数,_ref(month),_n(1){this-_year year;this-_month month;this-_day day;}
};//编译没有报错
int main()
{Date d1(2023, 11, 2);return 0;
} _a被初始化为了0。还是上面这段代码如果将A(int a 0)改成A(int a)编译就会报错因为没有合适的默认构造函数。 所以自定义类型在使用初始化列表的时候建议要显示地传参去调用指定的构造函数。
四、初始化列表使用的建议以及小点 尽量使用初始化列表初始化因为不管你是否使用初始化列表对于自定义类型成员变量 一定会先使用初始化列表初始化。 但是我们能不能什么地方都用初始化而都不在函数体内部赋初始值呢答案是不行的。初始化列表可以解决百分之九十的问题但对于一些像判断之类的语句还是要放在函数体内部的。像下面这个例子 class Date
{
private:int _year;int _month;int _day;int* _aa;public:Date(int year, int month, int day):_year(year) //aa没有显示地调用初始化列表会去调用它的默认构造函数, _month(month)//剩下的三个成员没有写出来定义但是它也会定义只是内置类型给的随机值, _day(day) //自定义类型会去调用它的默认构造函数,_aa(new int [10]){if (_aa nullptr){perror(new fail);exit(-1);}}~Date(){delete[] _aa;}
};int main()
{Date d1(2023, 11, 2);return 0;
} 这里有一个小点需要注意. 成员变量在类中声明次序就是其在初始化列表中的初始化顺序与其在初始化列表中的先后次序无关。 class A
{
public:A(int a):_a1(a), _a2(_a1){}void Print() {cout _a1 _a2 endl;}
private:int _a2;int _a1;
};int main()
{A aa(1);aa.Print();
} 上面代码_a2比_a1先声明所以_a2先初始化用_a1初始化_a2此时_a1为随机值所以初始化完_a2为随机值再用1初始化_a1_a1为1。