class Date{} //这是一个空类
如上图, 我们已经知道空类在计算大小的时候会占一个字节.
那么空类中确实什么都没有么? 其实, 任何一个类在没有内容的情况下, 都会自动生成6个默认成员函数. 它们分别是
下面, 让我们开始学习构造函数
class Date
{
public:
void SetDate(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
void Display()
{
cout << _year << " -" << _month << " -" << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1,d2;
d1.SetDate(2018,5,1);
d1.Display();
d2.SetDate(2018,7,1);
d2.Display();
return 0;
}
对于Date类, 可以通过SetDate公有的方式给对象设置内容, 但是如果每次创建对象都调用该方法设置信息, 未免有点麻烦.那能否在对象创建时. 就将信息设置进去呢?
构造函数是一个特殊的成员函数, 名字与类名相同, 创建类 类型对象时由编译器自动调用, 保证每个数据成员都有一个合适的初始值, 并且在对象的生命周期内只调用一次.
下面通过代码具体认知一下构造函数
构造函数是特殊的成员函数, 需要注意的是, 构造函数的虽然名称叫构造, 但是需要注意的是构造函数的主要任务并不是开空间创建对象, 而是初始化对象.
class Date
{
public:
//1, 无参构造函数
Date()
{}
//2, 带参构造函数
Date(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
//此处构成函数重载, 函数的形参不同
/* Date(int year = 1900, int month = 1, int day = 1)
{
_year = year;
_month = month;
_day = day;
}
// 如果替换成该注释部分, 此处将不构成函数重载, 编译错误, 因为全缺省的构造函数和无参的构造函数都属于默认构造函数, 默认构造函数只能有一个.*/
private:
int _year;
int _month;
int _day;
};
void TestDate()
{
Date d1; //调用无参构造函数
Date d2(2015,1,1);//调用带参的构造函数
//注意: 如果通过无参构造函数创建对象时, 对象后面不用加括号, 不然就成了函数声明
//比如这个例子
Date d3();
//这句代码声明了d3函数,该函数无参, 返回一个日期类型的对象.
}
至此, 让我们来总结一波构造函数的特征
特征如下:
1.函数名与类名相同.
2.无返回值
3.对象实例化时编译器自动调用对应的构造函数.
4.构造函数可以重载.
5. 构造函数重载是有限制的, 如果一个类中有同名的全缺省的构造函数和无参的构造函数,将不构成重载, 因为都属于默认构造函数, 而默认构造函数只能有一个.
那么构造函数有没有缺点呢? 我们再来对比一下构造函数Date(int,int,int)从使用和结构上来看和SetDate是比较接近的, 而无参的构造函数Date d1 在调用后,对象year/month/day依然是随机值, 那么这个构造函数的好处究竟在哪儿呢?
让我们先接着往下看
class Time
{
public:
//这是一个无参构造函数
Time()
{
cout<< "Time()" <<endl;
_hour = 0;
_minute = 0;
_second = 0;
}
private:
int _hour;
int _minute;
int _second;
};
这是一个时间类, 调用其构造函数时会将成员变量初始化. 比如说Time t1; 这条语句会对Time进行实例化, 返回一个Time 类的时候已经对成员变量进行了初始化. 这不就提高了效率么.
如果是在类里面又有一个类(即自定义的成员), 针对于这种情况, 构造函数会如何处理呢?
class Date
{
private:
//基本类型(内置类型)
int _year;
int _month;
int _day;
//自定义类型
Time _t; //这里是在Date类中定义了一个Time 类
};
int main()
{
Date d1;
return 0;
}
这段代码请大家自行调试验证, 可以发现int类型的年月日并没有被初始化, 而Time类中的时,分,秒被正确初始化为0了
解答: C++把类型分为内置类型(基本类型)和自定义类型. 内置类型就是语法已经定义好的类型: 如Int / char 等等 , 自定义类型就是我们使用class / struct / union自定义的类型 . 当我们进行调试时, 可以知道Date类默认生成的构造函数对内置类型并没有处理, 但是对于自定义类型Time类来讲, 调用了Time构造函数, 从而初始化了时,分,秒三个变量.
下面我们接着看一下成员变量的命名风格
//不好的成员变量命名
class Date
{
public:
Date(int year)
{
//这里的year到底是成员变量, 还是函数形参呢
year = year;
}
private:
int year;
};
//推荐的成员变量命名
class Date
{
public:
Date(int year)
{
_year = year;
}
private:
int year;
};
//另一种推荐的成员变量命名
class Date
{
public:
Date(int year)
{
m_year = year;
}
private:
int m_year;
};
下一篇_析构函数