Welcome to 9ilk's Code World
(๑•́ ₃ •̀๑) 个人主页: 9ilk
(๑•́ ₃ •̀๑) 文章专栏: 与C++的邂逅
本节我们继续学习类与对象下,下面给出本节内容大纲。
🏠 再谈构造
📌 构造函数体赋值
在创建对象时,编译器通过调用构造函数,给对象中各个成员变量一个合适的初始值
。
class Date
{
public:
Date(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
private:
int _year;
int _month;
int _day;
};
虽然上述构造函数调用之后,对象中已经有了一个初始值,但是不能将其称为对对象中成员变量的初始化,构造函数体中的语句只能将其称为赋初值,是一种"伪初始化",而不能称作初始化。因为初始化只能初始化一次,而构造函数体内可以多次赋值。
📌 初始化列表
class Stack
{
public:
Stack(size_t capacity)
{
//..
}
private:
int _top;
int _array;
int _size;
};
class MyQueue
{
private:
Stack _pushst;
Stack _popst;
int _size;
};
int main()
{
MyQueue q;
return 0;
}
对于MyQueue这样的类,我们建议构造时使用编译器默认生成的构造,此时对它的自定义类型成员调用默认构造,但是Stack类中由于显示实现了有参构造,此时没有默认构造,该如何对MyQueue类对象初始化呢?
初始化列表:以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个"成员变量"后面跟一个放在括号中的初始值或表达式。
此时可以利用初始化列表进行初始化,在初始化列表中显示对自定义类型调有参构造:
MyQueue(int n) //显示写构造
:_pushst(n),
_popst(n),
_size(0)
{}
对于初始化列表我们需要了解以下几点:
-
每个成员变量在初始化列表中只能出现一次(初始化只能初始化一次),初始化列表本质上可以理解为每个对象中成员定义的地方(毕竟类只能在定义的时候构造).
class MyQueue
{
public:
MyQueue(int n) //显示写构造 定义的地方
:_pushst(n),
_popst(n),
_size(0)
{}
private: //声明
Stack _pushst;
Stack _popst;
int _size;
};
-
类中所有成员既可以在初始化列表初始化,也可以在函数体;但以下类型必须在初始化列表初始化:
1. const成员变量。(const修饰变量只有一次初始化机会,需要在定义时给他一个值)2. 引用成员变量。(引用定义时需要给他一个值,而且不能改变指向)3.无默认构造的自定义类型成员。(这类成员必须显示传参调构造)
- 尽量使用初始化列表初始化。因为不管你是否显示写,成员变量都会走初始化列表,自定义类型调用它的默认构造。
- 缺省值是给初始化列表准备的。
1. 内置类型有缺省值初始化列表用缺省值,没有的话不确定,看编译器,有的编译器会处理,有的不会处理。
2. 自定义类型成员初始化列表会调用默认构造(没有默认构造会编译报错),自定义类型成员在声明时也可以给缺省,如果初始化列表显示调用该成员构造就不用这个缺省。
- 初始化列表对成员变量的初始化内容可以是变量,常量,表达式,函数调用等。
int fun()
{
return 1;
}
MyQueue(int