一、类定义的基本语法
类定义的核心语法格式如下:
class 类名
{
public:
公有成员声明; // 对外接口,类外部可以访问
protected:
保护成员声明; // 继承相关,类外部不可访问,派生类可访问
private:
私有成员声明; // 内部实现细节,类外部不可访问
}; // 注意末尾的分号Code language: PHP (php)
其中 public、protected、private 称为访问限定符,用来控制类成员的不同访问权限。
二、时钟类的定义示例
以时钟为例,一个完整的类定义如下:
class Clock
{
private:
int hour, minute, second; // 数据成员:存储属性,描述"是什么/有什么"
public:
void ShowTime(); // 成员函数声明(仅原型)
void SetTime(int h, int m, int s); // 成员函数声明(仅原型)
};Code language: JavaScript (javascript)
分析:
| 部分 | 说明 |
|---|---|
class Clock | 定义类名为 Clock,Clock 成为一种新的用户自定义类型 |
private 数据成员 | hour、minute、second 三个整型变量,存储时钟的时、分、秒状态 |
public 成员函数 | ShowTime() 和 SetTime() 是类对外提供的接口,外部代码通过它们与 Clock 对象交互 |
| 函数仅声明原型 | 类体内只写函数原型(返回值类型 + 函数名 + 参数列表 + 分号),函数体在类外定义 |
三、类内声明与类外定义成员函数
在类中可以只声明函数的原型,函数的实现(即函数体)放在类外定义。类外定义时必须使用作用域限定符 :: 指明函数所属的类。
语法格式:
返回值类型 类名::函数名(参数列表)
{
// 函数体
}Code language: JavaScript (javascript)
以 Clock 类为例,类外定义成员函数:
#include <iostream>
using namespace std;
class Clock
{
private:
int hour, minute, second;
public:
void ShowTime();
void SetTime(int h, int m, int s);
};
// 类外定义 SetTime
void Clock::SetTime(int h, int m, int s)
{
if (h >= 0 && h < 24)
hour = h;
else
hour = 0;
if (m >= 0 && m < 60)
minute = m;
else
minute = 0;
if (s >= 0 && s < 60)
second = s;
else
second = 0;
}
// 类外定义 ShowTime
void Clock::ShowTime()
{
if (hour < 10) cout << "0";
cout << hour << ":";
if (minute < 10) cout << "0";
cout << minute << ":";
if (second < 10) cout << "0";
cout << second << endl;
}Code language: PHP (php)
注意 Clock:: 前缀:Clock::SetTime 表示 SetTime 是 Clock 类的成员函数,而不是一个全局函数。如果省略 Clock::,编译器会将其视为普通全局函数,链接时会报错。
四、类内定义 vs 类外定义
| 方式 | 写法 | 特点 |
|---|---|---|
| 类内定义 | 函数体直接写在类 {} 内部 | 默认隐式为 inline(内联函数),函数体短小时推荐 |
| 类外定义 | 类内写原型,类外写函数体 | 类的定义更简洁,适合函数体较长或需要分离接口与实现的情况 |
// 类内定义(隐式 inline)
class Clock
{
private:
int h, m, s;
public:
void SetTime(int hh, int mm, int ss)
{
h = hh; m = mm; s = ss; // 函数体短小,直接写在类内
}
};
// 类外定义(非 inline,除非显式加 inline)
class Clock
{
private:
int h, m, s;
public:
void SetTime(int hh, int mm, int ss);
};
void Clock::SetTime(int hh, int mm, int ss)
{
h = hh; m = mm; s = ss;
}Code language: PHP (php)
五、访问限定符详解
| 限定符 | 类内部访问 | 类外部通过对象访问 | 派生类中访问 | 典型用途 |
|---|---|---|---|---|
public | 允许 | 允许 | 允许 | 对外接口(成员函数) |
protected | 允许 | 不允许 | 允许 | 继承体系中基类向派生类暴露的成员 |
private | 允许 | 不允许 | 不允许 | 内部数据成员和辅助函数 |
注意:
- 访问限定符可以出现多次,每次出现到下一个限定符之间的成员受其控制。
- 如果类中不写任何访问限定符,默认全部为
private(与struct不同,struct默认为public)。 - 通常将数据成员设为
private,将成员函数设为public,必要时将部分函数设为private作为内部辅助。
六、完整的时钟类使用示例
#include <iostream>
using namespace std;
class Clock
{
private:
int hour, minute, second;
public:
void ShowTime();
void SetTime(int h, int m, int s);
};
void Clock::SetTime(int h, int m, int s)
{
if (h >= 0 && h < 24)
hour = h;
else
hour = 0;
if (m >= 0 && m < 60)
minute = m;
else
minute = 0;
if (s >= 0 && s < 60)
second = s;
else
second = 0;
}
void Clock::ShowTime()
{
if (hour < 10) cout << "0";
cout << hour << ":";
if (minute < 10) cout << "0";
cout << minute << ":";
if (second < 10) cout << "0";
cout << second << endl;
}
int main()
{
Clock c1, c2; // 创建两个 Clock 对象
c1.SetTime(8, 30, 0); // 通过对象调用公有成员函数
c2.SetTime(19, 45, 30);
cout << "c1 时间:";
c1.ShowTime();
cout << "c2 时间:";
c2.ShowTime();
// c1.hour = 10; // 错误:hour 是 private,类外不可访问
return 0;
}Code language: PHP (php)
七、注意事项
- 类定义末尾的分号
;不可省略,这是初学者最常见的错误。 - 类外定义成员函数时,必须加
类名::前缀,否则编译器视为全局函数。 - 类外定义成员函数时,参数名可以和类内声明时不同,但参数类型、个数、顺序必须一致。
// 类内声明
void SetTime(int h, int m, int s);
// 类外定义(参数名可以不同)
void Clock::SetTime(int hour, int minute, int second)
{
// ...
}Code language: JavaScript (javascript)
- 一个类可以包含另一个类的对象作为成员(组合关系),但类不能包含自身类型的对象(可以包含自身类型的指针或引用)。
- 类定义通常放在头文件(
.h)中,成员函数的类外实现放在源文件(.cpp)中,这是工程开发的标准做法。
八、常见错误
1. 忘记类定义末尾的分号
class Clock
{
// ...
} // 错误:缺少分号Code language: JavaScript (javascript)
2. 类外定义时遗漏类名限定符
void SetTime(int h, int m, int s) // 错误:不是 Clock 的成员
{
hour = h; // 找不到 hour
}Code language: JavaScript (javascript)
正确写法:
void Clock::SetTime(int h, int m, int s)
{
hour = h;
}Code language: JavaScript (javascript)
3. 在类外定义时修改函数签名
// 类内声明
void SetTime(int h, int m, int s);
// 类外定义(错误:返回值类型不同)
int Clock::SetTime(int h, int m, int s) // 错误
{
// ...
}Code language: JavaScript (javascript)
4. 试图在类外直接访问私有成员
void printHour(Clock c)
{
cout << c.hour; // 错误:hour 是 private
}Code language: JavaScript (javascript)
解决:通过公有接口 c.ShowTime(); 或提供公有 getter 函数。