再谈构造函数
初始化列表
问题描述:虽然之前调用构造函数后,对象中的成员变量已经有了初始值,但是这仍然不能称之为对对象中成员变量的初始化,只能叫做赋初值,因为成员变量只能被初始化一次,而之前的构造函数内可以进行多次“初始化”
基本概念:初始化列表是每个成员变量定义初始化的位置
格式:
class Date
{
public:
Date(int year, int month, int day)
: _year(year)
, _month(month)
, _day(day)
{
//函数体
}
private:
int _year; //缺省值
int _month;
int _day;
};
注意事项:
1、最好使用初始化列表初始化成员变量,因为即使不用默认构造函数也会先看看初始化列表中有没有东西然后再去看函数体中的内容
2、在初始化列表中自定义类型的成员变量在初始化时默认调用它们的默认构造函数(即使在原内容中并没有明确的写出要初始化该自定义类型的成员变量,如果没有默认构造函数就会报错)
#include <iostream>
using namespace std;
class B
{
public:
//全缺省的默认构造函数
B(int a = 1)//参数的个数最好和
:_a(a)
{
cout << "B(int a)" << endl;
}
private:
int _a;
};
class A
{
public:
A(int year, int month, int day, int& x)
: _year(year)
, _month(month)
, _day(day)
, _n(1)
, _ref(x)
, _aa(1)
{
}
private:
//声明
int _year;
int _month;
int _day;
//必须初始化
const int _n;
int& _ref;
B _aa;
};
int main()
{
int x = 10;
A d1(2024, 1, 31, x);
return 0;
}
调试过程: 20240310_233253-CSDN直播
如果没有默认构造就,可以直接显式调用(在初始化列表中给初始化参数):
A(int year, int month, int day, int& x)
: _year(year)
, _month(month)
, _day(day)
, _n(1)
, _ref(x)
, _aa(1)
{
}
调试过程:20240310_234732-CSDN直播
如果有默认构造而且初始化列表中也有初始化,那么就按照初始化列表中给的参数来:
#include <iostream>
using namespace std;
class B
{
public:
B(int a = 1)
:_a(a)
{
cout << "B(int a)" << endl;
cout << a << endl;
}
private:
int _a;
};
class A
{
public:
A(int year, int month, int day, int& x)
: _year(year)
, _month(month)
, _day(day)
, _n(1)
, _ref(x)
, _aa(10)
{
}
private:
//声明
int _year;
int _month;
int _day;
//必须初始化
const int _n;
int& _ref;
B _aa;
};
int main()
{
int x = 10;
A d1(2024, 1, 31, x);
return 0;
}
3、 引用成员变量、const成员变量、自定义类型成员变量(且该类没有默认构造函数时)必须放在初始化列表中进行初始化
#include <iostream>
using namespace std;
class B
{
public:
B(int a, int b)//参数的个数应该和传入的参数个数相同(_aa(1,2)),即使不用
:_a(a)
,_b(b)
{
cout << "B(int a,int b)" << endl;
cout << a << endl;
cout << b << endl;
}
private:
int _a;
int _b;
};
class A
{
public:
A(int year, int month, int day, int& x)
: _year(year)
, _month(month)
, _day(day)
, _n(1)
, _ref(x)
, _aa(1, 2)
{
}
private:
//声明
int _year;
int _month;
int _day;
//必须初始化
const int _n;
int& _ref;
B _aa;
};
int main()
{
int x = 10;
A d1(2024, 1, 31, x);
return 0;
}
4、一个成员变量只能在初始化列表中出现一次
5、缺省值是给初始化列表用的(在初始化列表中没有给初始化值成员变量才会用缺省值)
6、成员变量在类中的声明次序就是它在初始化列表中的初始化顺序,与初始化列表中的次序无关
7、初始化列表与结构体要(可以)配合使用
#include <iostream>
using namespace std;
class B
{
public:
B(int a, int b)//参数的个数最好和
:_a(a)
,_b(b)
{
cout << "B(int a,int b)" << endl;
cout << a << endl;
cout << b << endl;
}
private:
int _a;
int _b;
};
class A
{
public:
A(int year, int month, int day, int& x)
: _year(year)
, _month(month)
, _day(day)
, _n(1)
, _ref(x)
, _aa(1, 2)
,_p((int*)malloc(sizeof(4)))
{
if (_p == nullptr)
{
perror("malloc fail");
}
}
private:
//声明
int _year;
int _month;
int _day;
//必须初始化
const int _n;
int& _ref;
B _aa;
int* _p;
};
int main()
{
int x = 10;
A d1(2024, 1, 31, x);
return 0;
}
8、 先进行初始化队列中的初始化后进行函数体中内容(初始化或者其它内容)
9、
static成员
友元
内部类
匿名对象
拷贝对象时的一些编译器优化
再次理解封装
~over~