struct 与 class 对比
本课属于 Coddy C++ 学习旅程的“面向对象编程”单元。第 37 课,共 104 课。
在 C++ 中,struct 和 class 几乎完全相同。它们都可以有成员变量、成员函数和构造函数,也都支持继承。唯一的区别是它们的默认访问级别。
在 class 中,成员默认是 private。在 struct 中,成员默认是 public:
struct Point {
int x; // 默认是公有的
int y; // 默认是公有的
};
class Circle {
double radius; // 默认是私有的
public:
double getRadius() { return radius; }
};这也适用于继承。struct 默认采用 public 继承,而 class 默认采用 private 继承:
struct DerivedStruct : Base {}; // 公有继承
class DerivedClass : Base {}; // 私有继承除了这些默认设置之外,没有技术上的区别。不过,惯例很重要。
大多数 C++ 程序员会用 struct 表示成员公开的简单数据容器(例如坐标或配置),而在封装和行为很重要时使用 class。遵循这一惯例能让其他开发者更清楚地理解你的代码意图。
挑战
简单让我们构建一个简单的配置系统,演示如何按照 C++ 约定选择使用 struct 还是 class。你将创建一个用于存放简单数据、数据可公开访问的 struct,以及一个用于存放需要封装并控制访问权限的数据的 class。
你将创建两个文件来组织代码:
Config.h:定义一个结构体和一个类,分别表示不同类型的配置数据。首先,创建一个名为
Dimensions的struct:它是一个简单的数据容器,用于存放宽度和高度(两者都是int)。由于结构体的成员默认是 public,这些成员应当可以直接访问,无需使用 getter。添加一个area()方法,返回宽度与高度的乘积。然后,创建一个名为
AppConfig的class,用适当的封装来管理应用设置。它应存储应用名称(字符串)和一个表示窗口大小的Dimensions对象。由于类成员默认是 private,你需要明确设置哪些内容可以通过公共接口访问。请提供:- 一个接收应用名称、宽度和高度的构造函数
- 一个返回名称的 getter
getAppName() - 一个返回
Dimensions的 gettergetWindowSize() - 一个打印以下内容的方法
displayConfig():"App: <name>, Window: <width>x<height>, Area: <area>"
main.cpp:演示 struct 和 class 的不同用法。从输入中读取应用名称、宽度和高度(三行分别输入),然后:- 使用宽度和高度的值直接创建一个
Dimensions结构体:直接访问其成员并打印以下内容:"Direct struct access: <width> x <height>" - 使用全部三个值创建一个
AppConfig对象 - 调用
displayConfig()显示完整配置 - 使用 getter 获取窗口尺寸并打印以下内容:
"Via getter - Area: <area>"
- 使用宽度和高度的值直接创建一个
这个挑战重点说明了一个约定:对于简单、透明的数据(例如坐标或尺寸),使用 struct;如果你想控制访问权限,并围绕数据添加行为,则使用 class。
使用 std::stoi() 将宽度和高度输入从字符串转换为整数。别忘了在头文件中添加头文件保护。
亲手试试
#include <iostream>
#include <string>
#include "Config.h"
using namespace std;
int main() {
// 读取输入
string appName;
string widthStr;
string heightStr;
getline(cin, appName);
getline(cin, widthStr);
getline(cin, heightStr);
int width = stoi(widthStr);
int height = stoi(heightStr);
// TODO:创建包含 width 和 height 的 Dimensions 结构体
// 直接访问它的成员并打印:"Direct struct access: <width> x <height>"
// TODO:用 appName、width 和 height 创建 AppConfig 对象
// TODO:调用 AppConfig 对象的 displayConfig() 方法
// TODO:使用 getWindowSize() 获取尺寸并打印:"Via getter - Area: <area>"
return 0;
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: C++ 在线编译器