(一) 类与对象
想让每个学生同时拥有姓名、成绩和及格判断,可以从模板章的小记录继续扩展,而不是用互不相关的变量维护同一个人。
可以把类(class)理解为一种自定义类型,把对象(object)理解为该类型的具体实例。类把相关数据和操作放在一起,例如学生的姓名、成绩和判断是否及格的方法。
区分类本身和每个对象的数据。 Student 定义了学生记录的组成和可执行操作;Student alice; Student bob; 创建两个实例。修改 alice.score 不会修改 bob.score,因为普通非静态数据成员分别属于各自对象。调用 alice.passed() 时,函数读取的是 alice 的成绩。
类的作用是让“属于同一个对象的数据和操作”有明确位置。竞赛中把边的终点、权值放进 Edge,比用两个独立数组再手工维持相同下标更容易理解。是否需要隐藏数据、继承或虚函数,要由问题决定;一个只有公开数据的 struct 也可以是合适的设计。
这里先把 class 当成带数据和成员函数的自定义类型阅读;public: 之后的成员允许类外访问,passed() 通过当前对象的 score 判断。下一节再收紧成绩的修改权限。
#include <iostream>
#include <string>
using namespace std;
class Student {
public:
string name;
int score = 0;
bool passed() const { // const 表示判断成绩时不修改当前对象。
return score >= 60;
}
};
int main() {
Student student;
student.name = "Alice";
student.score = 85;
cout << student.name << ' ' << student.passed() << '\n'; // Alice 1
}说明:
name、score是数据成员;passed()是成员函数。object.member访问对象成员;pointer->member通过有效指针访问成员。struct和class都可以拥有成员函数、构造函数和继承关系。它们的主要语法差异是默认成员访问权限和默认继承权限:struct为public,class为private。
竞赛中常用 struct Edge { int to; long long weight; }; 表示一条边,不必把所有结构都写成复杂的类。