类的定义

一、类定义的基本语法

类定义的核心语法格式如下:

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 函数。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注