主要总结C++类与对象的一些语法,建议读者先了解什么是类什么是对象再来阅读。
定义类和成员函数
C++的类定义包括属性及成员函数,且分为公有成员和私有成员。
- 公有成员在程序的任意地方直接访问。
- 私有成员只能在成员函数的定义中使用。
#include <iostream>
using namespace std;
class DayOfYear
{
public:
void input();
void output();
void set(int newMonth, int newDay);
// 前条件:newMonth 和 newDay 构成一个可能的日期
// 后条件:日期根据传递的实参来重置
int getMonth();
// 返回月份,1代表1月,2代表2月,依次类推
int getDay();
// 返回天数
private:
void checkDate();
int month;
int day;
};
int main()
{
DayOfYear today, bachBirthday;
cout<<"Enter today's date:\n";
today.input();
cout<<"Today's date is ";
today.output();
bachBirthday.set(3, 21);
cout<< "J. S. Bach's birthday is ";
bachBirthday.output();
if ( today.getMonth() == bachBirthday.getMonth() &&
today.getDay() == bachBirthday.getDay() )
cout<<"Happy Birthday Johann Sebastian!\n";
else
cout<<"Happy Unbirthday Johann Sebastian!\n";
return 0;
}
// 使用 iostream
void DayOfYear::input()
{
cout<<"Enter the month as a number: ";
cin>>month;
cout<<"Enter the day of the month: ";
cin>>day;
checkDate();
}
void DayOfYear::output()
{
cout<< "month = " <<month
<< ", day = " << day << endl;
}
void DayOfYear::set(int newMonth, int newDay)
{
month = newMonth;
day = newDay;
checkDate();
}
void DayOfYear::checkDate()
{
if( (month < 1) || (month > 12) || (day < 1) || (day > 31) )
{
cout<<"Illegal date. Aborting program.\n";
exit(1); // 用于退出程序
}
}
int DayOfYear::getMonth()
{
return month;
}
int DayOfYear::getDay()
{
return day;
}
上面代码中的所有类属性都是私有属性,一般情况对其修改使用 set 方法,获得属性使用使用 get 方法,这可以被称为封装,也叫数据隐藏,目的是使类中的变量私有,只能由公共或受保护函数通过一个受控制的接口访问。这样就可以自由修改内部变量和数据结构,而不影响使用类的代码。
构造函数
定义类时,可定义一种特殊的成员函数,称为构造函数。构造函数在声明类的对象时自动调用。构造函数通常初始化成员变量的值,并进行其他初始化操作。可像定义其他任何成员函数那样来定义构造函数,只是注意以下三点。
- 其一,构造函数必须与类同名。例如,假定类名是 DayOfYear,则该类的构造函数必须命名为 DayOfYear。
- 其二,构造函数定义不能返回值。此外,在函数声明起始处或函数头中,不允许指定返回类型(连 void 都不可以)。
- 其三,构造函数只能作为公有成员,作为私有成员会出错。
将构造函数加入上面的示例代码中。
#include <iostream>
using namespace std;
class DayOfYear
{
public:
DayOfYear(int Month, int Day);
DayOfYear();
void input();
void output();
void set(int newMonth, int newDay);
// 前条件:newMonth 和 newDay 构成一个可能的日期
// 后条件:日期根据传递的实参来重置
int getMonth();
// 返回月份,1代表1月,2代表2月,依次类推
int getDay();
// 返回天数
private:
void checkDate();
int month;
int day;
};
int main()
{
DayOfYear today(3, 22);
cout<<"Today's date is ";
today.output();
DayOfYear bachBirthday; // 注意这里没有括号
cout<< "J. S. Bach's birthday is ";
bachBirthday.output();
if ( today.getMonth() == bachBirthday.getMonth() &&
today.getDay() == bachBirthday.getDay() )
cout<<"Happy Birthday Johann Sebastian!\n";
else
cout<<"Happy Unbirthday Johann Sebastian!\n";
return 0;
}
DayOfYear::DayOfYear(int Month, int Day)
{
month = Month;
day = Day;
checkDate();
}
DayOfYear::DayOfYear()
{
month = 3;
day = 21;
checkDate();
}
// 使用 iostream
void DayOfYear::input()
{
cout<<"Enter the month as a number: ";
cin>>month;
cout<<"Enter the day of the month: ";
cin>>day;
checkDate();
}
void DayOfYear::output()
{
cout<< "month = " <<month
<< ", day = " << day << endl;
}
void DayOfYear::set(int newMonth, int newDay)
{
month = newMonth;
day = newDay;
checkDate();
}
void DayOfYear::checkDate()
{
if( (month < 1) || (month > 12) || (day < 1) || (day > 31) )
{
cout<<"Illegal date. Aborting program.\n";
exit(1); // 用于退出程序
}
}
int DayOfYear::getMonth()
{
return month;
}
int DayOfYear::getDay()
{
return day;
}
类的构造函数和类的其他函数可以重载。需要注意的是如果未定义构造函数,程序会自动生成一个默认的构造函数,其为空语句。但是如果我们定义了构造函数,那么程序就不会生成默认的构造函数,此时如果没有默认构造函数,如果直接默认定义会出错,一般会自己定义一个默认构造函数,比如这里的 DayoOfYear()
。
这里可以冒号来简化构造函数。
DayOfYear::DayOfYear(int Month, int Day)
: month(Month), day(Day)
{
checkDate();
}
DayOfYear::DayOfYear()
: month(3), day(21)
{
checkDate();
}
我们可以显示调用构造函数创建类的新对象。
DayOfYear NewDate = DayOfYear(3, 20);
其相当于先生成一个匿名对象,再将其赋给一个对象。
如果对象作为动态变量创建,可以使用 new
操作。
DayOfYear *NewDate;
NewDate = new NewDate(3, 20);
我们甚至可以直接在类中赋值以进行初始化,如果有构造函数会被覆盖。
private:
int month = 3;
int day = 21;
抽象数据类型
数据类型由值的集合以及为那些值定义的一组基本运算构成。使用数据类型的程序员访问不了值和运算的实现细节,该数据类型就称为抽象数据类型(Abstract Data Type,ADT)。预定义类型(比如 int)就是抽象数据类型。对于 int 类型,你不知道 + 和 - 等运算具体如何实现。即使知道,也无法在任何 C++ 程序中利用这方面的信息。
生成抽象数据类型的类也很重要,可以让使用类的程序员不用关注实现细节。生成抽象数据类型的类需要遵循以下规则:
- 所有成员变量都设为类的私有成员。
- 用户程序员需要的每个基本操作都设为类的公共成员函数,并完善地规定如何使用每个公共成员函数。
- 任何辅助函数都设为私有成员函数。