构造函数
构造函数的概念
我们有一个Date
类
class Date
{
public:
void Init(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
void Print()
{
cout << _year << "-" << _month << "-" << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
对于Date
类,可以通过Init
共有方法给对象设置日期,但如果每次创建对象都调用这种方法就太烦了。于是我们可以用构造函数在对象创建时,就将信息设置进去。
构造函数是一个特殊的成员函数,名字与类名相同,创建类类型对象时由编译器自动调用,在对象整个生命周期里只调用一次。
构造函数的特性
构造函数不能顾名思义!!!。构造函数不是开辟空间创建对象,而是初始化对象。特征有以下4点:
- 函数名与类名相同。
- 没有返回值。
- 对象实例化时,编译器自动调用对应的构造函数。
- 构造函数可以函数重载。
class Date
{
public:
Date()
{}
Date(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
void Print()
{
cout << _year << "-" << _month << "-" << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1;//调用无参构造函数
Date d2(2022,7,22);//调用待参的构造函数
Date d3();//这是d3函数的声明,函数无参数,返回一个日期类型的对象
return 0;
}
- 如果类中没用显式定义构造函数(说人话就是你没自己写构造函数),则C++编译器自动生成一个无参的默认构造函数。一旦用户显式定义任何构造函数,编译器将不再生成。
class Date
{
public:
//如果用户显式定义里构造函数,编译器将不再生成
//Date(int year, int month, int day)
//{
// _year = year;
// _month = month;
// _day = day;
//}
void Print()
{
cout << _year << "-" << _month << "-" << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
//将Date类中的构造函数屏蔽后,代码可以通过编译,因为编译生成了一个无参的默认构造函数
//将Date类中的构造函数放开后,代码不可以通过编译,因为编译没有生成这种无参的构造函数
Date d1;
return 0;
}
- 不实现构造函数的情况下,编译器会自动生成默认的构造函数,但是d对象的
_year
等依旧是随机值,似乎编译器生成的默认构造函数没用?
C++把类型分成内置类型(基本类型)和自定义类型。内置类型就是语言提供的数据类型,如:int/char
…,自定义类型就是我们使用class/struct/union
等自己定义的类型。编译器生成默认的构造函数会对自定类型成员调用的它的默认成员函数,而对内置类型的量设为随机值。
这是C++设计的一个缺陷。C++11中针对内置类型成员不初始化的缺陷,又打了补丁,即:内置类型成员变量在类中声明时可以给默认值。
class Date
{
//...
private:
int _year = 2022;
int _month = 7;
int _day = 22;
};
- 无参的构造函数和全缺省的构造函数都称为默认构造函数,并且默认构造函数只能有一个。注意:无参
构造函数、全缺省构造函数、我们没写编译器默认生成的构造函数,都可以认为是默认构造函数。所以一下程序出现了“Date::Date”: 对重载函数的调用不明确
的报错。
class Date
{
public:
Date()
{
_year = 2022;
_month = 7;
_day = 1;
}
Date(int year = 2022, int month = 7, int day = 21)
{
_year = year;
_month = month;
_day = day;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1;//编译失败
return 0;
}