1.特性
构造函数是一个特殊的成员函数,是默认成员函数,构造函数的任务主要是初始化对象,其特征如下:
- 函数名与类名相同
- 无返回值 (不是void)
- 对象实例化时编译器自动调用对应的构造函数
- 构造函数可以重载 , 可以写多种构造函数,提供多种初始化方式
2. 用法
构造函数是为了方便我们定义一个新的对象的时候进行初始化的,这个函数我们不用自己写编译器也会自动帮我们调用,举个例子:
#include<iostream>
using namespace std;
class Date
{
public:
void Print()
{
cout << _year << '/' << _month << '/' << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1;
d1.Print();
return 0;
}
运行结果如下:
上面的代码中我并没有对d1进行初始化操作,而类中的打印函数却可以正常调用并且编译器没有报错,只不过输出的年月日是随机值而已,那如何证明编译器调用了构造函数呢?我们可以写一个Date构造函数来验证一下:
#include<iostream>
using namespace std;
class Date
{
public:
Date()
{
cout << "调用Date函数" << endl;
}
void Print()
{
cout << _year << '/' << _month << '/' << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1;
d1.Print();
return 0;
}
运行结果如下:
代码中可以看出,我并没有调用Date函数,这是编译器自己调用的,但是因为编译器构造的构造函数中并没有对成员变量进行赋值,因此打印出来的都是随机值,如果把构造函数和缺省参数结合起来,那就是一个非常完美的对象初始化操作,举个例子:
#include<iostream>
using namespace std;
class Date
{
public:
Date(int year = 1, int month =1 , int day = 1)
{
_year = year;
_month = month;
_day = day;
}
void Print()
{
cout << _year << '/' << _month << '/' << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1;
d1.Print();
return 0;
}
运行结果如下:
因为是全缺省的构造函数,因此当我们没有对对象进行传参时,则直接使用缺省参数进行初始化,若是想进行自定义初始化,则需要在定义新的对象之后进行传参举个例子,如果我想对上面的d1进行初始化操作,那我就再定义这个对象的时候进行传参初始化:
Date d1(2023,10,10);
此时的代码为:
#include<iostream>
using namespace std;
class Date
{
public:
Date(int year = 1, int month =1 , int day = 1)
{
_year = year;
_month = month;
_day = day;
}
void Print()
{
cout << _year << '/' << _month << '/' << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1(2023,10,10);
d1.Print();
return 0;
}
运行结果:
又因为是全缺省参数,默认值都是1,那此时我们如果想初始化一个d2日期为2023/1/1,那只需要传一个参数2023就可以了:
Date d2(2023);
此时的代码为:
#include<iostream>
using namespace std;
class Date
{
public:
Date(int year = 1, int month =1 , int day = 1)
{
_year = year;
_month = month;
_day = day;
}
void Print()
{
cout << _year << '/' << _month << '/' << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
/*Date d1(2023,10,10);
d1.Print();*/
Date d2(2023);
d2.Print();
return 0;
}
运行结果为:
这样就会非常方便
但是因为自动生成的构造函数不会对内置类型的成员进行处理,因此在C++11 中增加了对成员变量进行缺省定义的操作,举个例子:
class Date
{
private:
int _year = 1; //缺省参数
int _month = 1;
int _day =1;
};
此时我在定义这个类的成员变量时对成员变量进行了缺省,那么编译器自动调用的构造函数就会直接使用这些缺省值:
#include<iostream>
using namespace std;
class Date
{
public:
void Print()
{
cout << _year << '/' << _month << '/' << _day << endl;
}
private:
int _year = 1; //缺省参数
int _month = 1;
int _day =1;
};
int main()
{
Date d1;
d1.Print();
return 0;
}
运行结果如下:
但是此时的调用无法和自己写了全缺省的构造函数达到同样的效果,只能进行最简单的调用,并不能像全缺省的构造函数那样部分传参或全部传参:
3. 总结
- 构造函数自己不写那编译器会自动生成,只是自动生成的构造函数不会进行任何操作,仅仅只是生成函数而已.,但是自己写一个构造函数就不会自动生成.
- 构造函数要灵活控制,根据自己的需求来写,根据情况而进行改变
- 构造函数一般自己写成全缺省的会更加方便
- 自定义类型的成员才会处理,会去调用这个成员的构造函数
- 无参构造函数,全缺省构造函数和编译器自动生成的构造函数都可以认为是默认构造函数(不传参就能调用的),并且默认构造函数只能有一个.
完结❀❀❀