类的6个默认成员函数:构造函数、拷贝构造函数、析构函数、赋值操作符重载、取地址操作符重载
const修饰的取地址操作符重载
接下来的几篇博客会一一为大家介绍这几个成员函数
构造函数:
概念:构造函数是一个特殊的成员函数,名字与类名相同,创建类类型对象时,由编译器自动调用
在对象的生命周期内只调用一次,保证每个数据成员都有一个合适的初始值
例子:
class Date
{
public:
Date(int year, int month, int day) //构造函数
{
_year = year;
_month = month;
_day = day;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d(2018, 8, 31);
return 0;
}
构造函数特性:
1.函数名与类名相同 2.没有返回值 3.构造函数可以重载,实参决定了调用哪个构造函数
4.无参构造函数和带有缺省值的构造函数都认为是缺省的构造函数,并且缺省的构造函数只能有一个
5.有初始化列表(可以不用) 6.如果没有显式定义,编译器会合成一个默认的构造函数
对象初始化:
初始化列表:以一个冒号开始,接着是一个以逗号分隔的数据成员列表,
每个“成员变量”后面跟一个放在括号中的初始值或表达式
例子:
class Student
{
public:
Student()
:_age(15), _name('a')
{}
void print()
{
cout << "_age" << _age << "_name" << _name << endl;
}
private:
int _age;
char _name;
};
注意:
1.每个成员在初始化列表中只能出现一次
2.初始化列表仅仅用于初始化类的数据成员,并不能指定这些数据成员初始化顺序
数据成员在类中定义的顺序就是在参数列表中的初始化顺序
3.尽量避免使用成员初始化成员,成员初始化顺序最好和成员的定义顺序保持一致
4.类中包含以下成员,一定要放在初始化列表位置进行初始化:
引用成员变量、const成员变量、类类型成员(该类有非缺省的构造函数)
构造函数作用:
1.构造并且初始化对象
2.类型转换:对于单个参数构造函数,可以将其接受参数转化成类类型对象。用explicit
修饰构造函数,抑制构造函数定义的隐式转换,explicit关键字在类内部的构建
声明上,在类的定义体外的定义上不再重复。
问几个问题:
什么情况下下需要给出构造函数
在创建对象的时候需不需要给出初始值,如果需要初始值就把构造函数给出
什么情况下编译器自动合成构造函数?
参考这篇文章 https://blog.csdn.net/zyl_1102179268/article/details/60370626
什么样的构造函数具有类型转化的作用?
只针对单餐构造函数,可以将其接收参数转化为类类型对象
class Date
{
public:
Date(int year)
:_year(year)
{}
private:
int _year;
};
int main()
{
Date d1(2018);
//用一个整形变量给d1对象赋值
//实际编译器背后会用2019构造一个无名对象,最后用无名对象给d1对象进行赋值
d1 = 2019;
return 0;
}
什么时候调用构造函数?什么时候调用拷贝构造函数?
创建对象时使用已经存在的同类对象来进行初始化调用拷贝构造函数,其他情况调用构造函数
构造函数不能用const修饰,为什么?
const修饰函数表示该函数的返回值是const类型,该返回值只能赋值给同类型的const变量
const是可以修饰类的成员函数,但是该函数不能修改数据成员,构造函数也属于类的成员函数
构造函数是要修改类的成员变量,所以类的构造函数不能用const修饰
构造函数不能为虚函数为什么?(重点)
1.虚函数的作用是什么?是实现部分或默认的功能,而且该功能可以被子类所修改,如果父类
的构造函数设置成虚函数,那么子类的构造函数会直接覆盖掉父类的构造函数。而父类的构造
函数就会失去一些初始化的功能,
2.虚函数的调用是需要通过“虚函数表”来进行,而虚函数表也需要在对象实例化之后才能进行调用
在构造对象的过程中,还没有为“虚函数表”分配内存,所以这个调用违背了实例化后调用的准则
3.虚函数的调用是由父类指针进行完成的,而对象的构造是由编译器完成的,由于在创建一个对象
过程中,涉及到资源的创建,类型的确定,这些是无法在运行过程中确定的,需要在编译的过程
中就确定下来。多态实在运行过程中体现出来的,所以不能通过虚函数来创建构造函数的,
与实例化的次序不同也有关系。
那么析构函数为什么可以设计成虚函数呢?由于虚函数是释放对象的时候才执行的,所以一开始
也就无法确定析够函数的。而去由于析构的过程中,是先析构子类对象,后析构父类对象。
所以,需要通过虚函数来指引子类对象。所以,如果不设置成虚函数的话,析构函数是无法执行子类的析构函数的