Menu
CoddyTech

信息隐藏

本课属于 Coddy C++ 学习旅程的“面向对象编程”单元。第 36 课,共 104 课。

信息隐藏不仅仅是使用访问修饰符。它是一种设计原则,要求你不仅隐藏数据,还要隐藏类内部的实现细节。

目标是只公开类的使用者需要了解的内容,同时隐藏其他所有内容。这样,你就可以更改内部实现,而不会影响使用这个类的代码:

class Temperature {
    double kelvin;    // 内部表示,隐藏的实现细节
    
public:
    void setCelsius(double c) {
        kelvin = c + 273.15;    // 转换过程对用户隐藏
    }
    
    double getCelsius() const {
        return kelvin - 273.15;
    }
    
    double getFahrenheit() const {
        return (kelvin - 273.15) * 9.0/5.0 + 32;
    }
};

这个类的用户不知道(也不需要知道)温度在内部以开尔文存储。如果你之后决定改用摄氏度存储,只需更改私有实现,公共接口保持不变。

这种将接口与实现分离的做法有几个好处:它降低了类用户的使用复杂度,避免内部数据被意外误用,也让代码更容易维护。隐藏内部细节后,你可以自由地优化或重构,而不会破坏依赖于你的类的现有代码。

challenge icon

挑战

简单

我们来创建一个 Distance 类,通过在内部以厘米存储距离来演示信息隐藏,同时提供简洁的接口,让你可以使用不同的单位。使用这个类的人不需要知道(也不必关心)距离在内部是如何存储的,他们只需使用方便的单位即可。

你将创建两个文件来组织代码:

  • Distance.h:定义一个 Distance 类,隐藏内部表示形式,同时提供灵活的公共接口。在内部,以 厘米(使用 double)存储距离。这是隐藏的实现细节。公共接口应允许用户:
    • 使用 setMeters(double m)、setCentimeters(double cm) 或 setKilometers(double km) 设置距离
    • 使用 getMeters()、getCentimeters() 或 getKilometers() 获取距离:它们都应是 const 方法
    • 使用 add(const Distance& other) 将两个距离相加,并返回一个新的 Distance 对象

    添加一个默认构造函数,将距离初始化为零。转换逻辑应隐藏在方法中:用户只需调用 setKilometers(5) 和 getMeters(),无需担心内部存储格式。

  • main.cpp:演示用户无需了解内部表示形式,也能使用这个类。从输入中读取两个距离值:第一个以米为单位,第二个以千米为单位。然后:
    • 创建一个 Distance 对象,并使用以米为单位的值设置它
    • 打印 "In meters: <value> m"
    • 打印 "In centimeters: <value> cm"
    • 打印 "In kilometers: <value> km"
    • 创建第二个 Distance 对象,并使用以千米为单位的值设置它
    • 将两个距离相加并保存结果
    • 打印 "Combined in meters: <value> m"

信息隐藏的妙处在于,你以后可以将内部存储单位从厘米改为毫米(或其他单位),而无需更改用户与这个类交互的方式。即使实现发生变化,公共接口也能保持稳定。

使用 <iomanip> 中的 std::fixed 和 std::setprecision(2) 将所有输出值格式化为两位小数。使用 std::stod() 将输入字符串转换为双精度浮点数。

换算参考:1 米 = 100 厘米,1 千米 = 1000 米。

亲手试试

#include <iostream>
#include <string>
#include <iomanip>
#include "Distance.h"

using namespace std;

int main() {
    // 读取输入值
    string metersInput, kmInput;
    cin >> metersInput;  // 第一个值,单位为米
    cin >> kmInput;      // 第二个值,单位为千米
    
    // 使用 std::stod() 将字符串转换为 double 类型
    double metersValue = stod(metersInput);
    double kmValue = stod(kmInput);
    
    // 设置输出格式
    cout << fixed << setprecision(2);
    
    // TODO: 创建第一个 Distance 对象,并用米数值设置它
    
    // TODO: 输出 "In meters: <value> m"
    
    // TODO: 输出 "In centimeters: <value> cm"
    
    // TODO: 输出 "In kilometers: <value> km"
    
    // TODO: 创建第二个 Distance 对象,并用千米数值设置它
    
    // TODO: 使用 add() 方法将两个距离相加
    
    // TODO: 输出 "Combined in meters: <value> m"
    
    return 0;
}
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

面向对象编程中的所有课

自己练习: C++ 在线编译器