C++学习之——类与对象(构造函数二)

[本节内容]

再谈构造函数
1.构造函数赋初值
2.初始化列表
3.explicit关键字

之前博客讲过成员函数默认的构造函数https://blog.csdn.net/ly_6699/article/details/87870429

类的六个默认成员函数也在下面博客中讲到
类与对象https://blog.csdn.net/ly_6699/article/details/87870429

1.构造函数体赋初值

在创建对象时,编译器通过调用构造函数,给对象中各个成员变量一个合适的初始值。

class Date
{
public:
	Date(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
private:
	int _year;
	int _month;
	int _day;
};

虽然调用上述构造函数后,对象中已经有了一个初始值,但是不能将其认为是类对象成员的初始化,所以构造函数体内的语句只能将其称之为赋初值
区别在于初始化只能初始化一次,但构造函数体内可以多次赋值。

2.初始化列表

初始化列表:以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个“成员变量”后面跟一个放在括号中的初始值或者表达式

初始化列表也可以被认为是成员变量定义的地方
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.类中包含以下成员时必须放在初始化列表中进行初始化:
引用成员变量
const成员变量
类类型成员(该类没有默认的构造函数)

class A
{
public:
	A(int a)
		:_a(a)
	{}
private:
	int _a;
};
class B
{
public:                    //初始化
	B(int a, int ref)
		:_aobj(a)
		, _ref(ref)
		, _n(10)
	{}
private:                  //声明
	A _aobj;              //类类型且没有默认的构造函数
	int & _ref;           //引用
	const int _n;        //const
};

3.尽量使用初始化列表进行初始化,因为无论我们是否使用初始化列表,自定义类型的成员一定会先使用初始化列表进行初始化

class Time
{
public:
	Time(int hour = 0)
		:_hour(hour)
	{
		cout << "Time()" << endl;
	}
private:
	int _hour;
};
class Date
{
public:
	Date(int day)
	{}
private:
	int _day;
	Time _t;
};
int main()
{
	Date d(1);
	system("pause");
	return 0;
}

4.成员变量在类中的声明次序决定了初始化次序

class Array
{
public:                   
	Array(int size)
		:_size(size)
		,_array((int *)malloc(sizeof(int)*_size))       //错误代码! 由于要先初始化了_array,而此时的_size还未初始化
	{}
private:
	int* _array;
	int _size;
};

3.explicit 关键字

构造函数不仅可以构造初始化对象,对于单个参数的构造函数,还具有类型转换的作用。

class Date
{
public:
	/*Date(int year)
		:_year(year)
	{}*/
	explicit Date(int year)      //禁止隐式类型转换
		:_year(year)
	{}
	void show()
	{
		cout << _year << endl;
		cout << _month << endl;
	}
private:
	int _year;
	int _month;
};
void Test()
{
	Date d1(2018);   //_year=2018,_month为随机值
	Date d2 = 12;   //因为有 explicit,故编译失败
	//d2 隐式类型转换的过程:
      //1.用整型12构造一个匿名对象
      //2.匿名对象拷贝构造d2
      //3.优化为拷贝构造
}

用explicit 修饰的构造函数,将会禁止单参构造函数的隐式类型转换

猜你喜欢

转载自blog.csdn.net/ly_6699/article/details/87922079