1.构造函数
1.1 构造函数的定义
在类中,有一种特殊的成员函数,其函数名与类名相同,我们在创建类的对象的时候,该成员函数会被系统自动调用。这个成员函数被称为“构造函数”。
1.2 构造函数的用途
用于初始化类对象的数据成员。
class Time
{
public:
int m_Hour; //成员变量
int m_Minute;
int m_Second;
public:
Time(int hour, int minute, int second) //构造函数初始化成员变量
{
m_Hour = hour;
m_Minute = minute;
m_Second = second;
}
};
int main() {
Time time1(10, 58, 5);
cout << time1.m_Hour << ":" << time1.m_Minute << ":" << time1.m_Second; //10:58:5
}
1.3 构造函数的特性
(1)构造函数没有返回值。
(2)不可以手动调用构造函数。
(3)正常情况下,构造函数需被声明为public,这样才可被系统自动调用,来进行初始化类对象的成员变量。
(4)构造函数中若有多个构造函数,则创建类对象时也需带上这些参数。
1.4 类对象的常见初始化方式
class Time
{
public:
int m_Hour; //成员变量
int m_Minute;
int m_Second;
public:
Time(int hour, int minute, int second) //构造函数初始化成员变量
{
m_Hour = hour;
m_Minute = minute;
m_Second = second;
cout << "调用构造函数" << endl;
}
};
int main() {
Time time1 = Time(10, 58, 5);
Time time2(10, 58, 5);
Time time3 = Time{10, 58, 5};
Time time4 = {10, 58, 5};
Time time5 {10, 58, 5};
}
1.5 类中存在多个构造函数
class Time
{
public:
int m_Hour; //成员变量
int m_Minute;
int m_Second;
public:
Time(int hour, int minute, int second) //构造函数初始化成员变量
{
m_Hour = hour;
m_Minute = minute;
m_Second = second;
cout << "调用构造函数" << endl;
}
Time()
{
cout << "调用无参构造函数" << endl;
}
};
int main() {
Time time (10, 58, 5); //调用构造函数
//调用无参构造函数
Time time1 = Time(); //调用无参构造函数
Time time2;//调用无参构造函数, 不可以用Time time2(); 形式调用无参构造函数
Time time3 = Time{};
Time time4 = {};
Time time5{};
}
1.6 构造函数的默认参数
规定:
(1)默认值只能放在构造函数声明中,除非该函数没有声明。
#ifndef DAY02_TIME_H
#define DAY02_TIME_H
//类的声明
class Time
{
public:
int m_Hour; //成员变量
int m_Minute;
int m_Second;
public:
Time(int hour, int minute, int second = 59); //在声明时给变量默认值
Time();
};
#endif //DAY02_TIME_H
#include <iostream>
using namespace std;
#include "Time.h"
//构造函数定义
Time::Time(int hour, int minute, int second)
{
m_Hour = hour;
m_Minute = minute;
m_Second = second;
cout << "调用构造函数" << endl;
}
int main() {
Time time1 (10, 10); //调用构造函数,由于其中second在函数声明时默认值为59,故此处只给两个参数即可
cout << time1.m_Hour << ":" << time1.m_Minute << ":" << time1.m_Second; //10:10:59
}
(2)在多个参数的函数中,只要某个参数给了默认值,其后面所有参数都必须给默认值 。
//类的声明
class Time
{
public:
int m_Hour; //成员变量
int m_Minute;
int m_Second;
public:
Time(int hour, int minute = 10, int second = 59);//minute参数给了默认值,其后面的second参数也必须给默认值
Time();
};
(3)若类中同时存在两个参数的构造函数,同时,若给三个参数的构造函数一个默认参数,这时系统无法判断该调用哪种构造函数。
#ifndef DAY02_TIME_H
#define DAY02_TIME_H
//类的声明
class Time
{
public:
int m_Hour; //成员变量
int m_Minute;
int m_Second;
public:
Time(int hour, int minute, int second = 59); //三参数的构造函数,其中第三个参数默认
Time(int hour, int minute); //两参数的构造函数
};
#endif //DAY02_TIME_H
#include <iostream>
using namespace std;
#include "Time.h"
//构造函数定义
Time::Time(int hour, int minute, int second)
{
m_Hour = hour;
m_Minute = minute;
m_Second = second;
cout << "调用构造函数Time(int hour, int minute, int second)" << endl;
}
Time::Time(int hour, int minute)
{
m_Hour = hour;
m_Minute = minute;
cout << "调用构造函数Time(int hour, int minute)" << endl;
}
int main() {
// Time time1 (10, 10); //错误,无法判断调用三参数构造函数还是两参数构造函数
}
2. 隐式类型转换与explicit
(1)对于单参数的构造函数,系统会进行隐式类型转换
Time::Time(int hour)
{
m_Hour = hour;
cout << "调用构造函数Time(int hour)" << endl;
}
void func(Time time)
{
}
int main() {
Time time1 = 14; //调用构造函数Time(int hour), 系统做了隐式转换,即Time time1 = Time(14)
Time time2 = (12, 13, 14, 15); //调用构造函数Time(int hour),Time time1 = Time(15)
func(16);//调用构造函数Time(int hour), Time time = Time(16)
}
(2)利用explicit可以关掉构造函数的隐式类型转换功能
#ifndef DAY02_TIME_H
#define DAY02_TIME_H
//类的声明
class Time
{
public:
int m_Hour; //成员变量
public:
explicit Time(int hour); //explicit:该构造函数只能用于初始化和显示类型转换
};
#endif //DAY02_TIME_H
#include <iostream>
using namespace std;
#include "Time.h"
Time::Time(int hour)
{
m_Hour = hour;
cout << "调用构造函数Time(int hour)" << endl;
}
void func(Time time)
{
}
int main() {
//下面写法均错误,explicit Time(int hour); //explicit:该构造函数只能用于初始化和显示类型转换
// Time time1 = 14;
// Time time2 = (12, 13, 14, 15);
// Time time3 = {12}; //这也是隐式类型转换
// func(16);
}
(3)对于单参数的构造函数一般都声明为explicit
3 构造函数初始化列表
Time::Time(int hour, int minute, int second) : m_Hour(hour), m_Minute(minute), m_Second(second)
{
}
int main() {
Time time1(10, 58, 5);
cout << time1.m_Hour << ":" << time1.m_Minute << ":" << time1.m_Second; //10:58:5
}