news 2026/8/30 15:20:08

C++入门教程:结构体、枚举与类初探

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C++入门教程:结构体、枚举与类初探

本文是 C++ 系列教程的第 5 篇。上一篇讲解了数组、字符串与指针,本篇正式进入面向对象世界:结构体 struct、枚举 enum/enum class、类 class 的基本语法,理解 public/private 访问控制和构造函数初步。

一、结构体 struct

1.1 结构体的定义与使用

结构体是不同类型数据的集合,用于描述一个复合对象:

#include<iostream>#include<string>usingnamespacestd;// 定义学生结构体structStudent{string name;intage;doublescore;};intmain(){// 定义并初始化Student s1;// 默认构造s1.name="张三";s1.age=20;s1.score=88.5;// 列表初始化(C++11)Student s2={"李四",21,92.0};// 访问成员cout<<s1.name<<" "<<s1.age<<"岁 "<<s1.score<<"分"<<endl;cout<<s2.name<<" "<<s2.age<<"岁 "<<s2.score<<"分"<<endl;return0;}

1.2 结构体数组

#include<iostream>#include<string>usingnamespacestd;structStudent{string name;intage;doublescore;};intmain(){// 结构体数组Student students[3]={{"张三",20,88.5},{"李四",21,92.0},{"王五",19,76.5}};// 遍历并统计平均分doublesum=0;for(constStudent&s:students){cout<<s.name<<": "<<s.score<<"分"<<endl;sum+=s.score;}cout<<"平均分: "<<sum/3<<endl;return0;}

1.3 结构体指针与传参

#include<iostream>#include<string>usingnamespacestd;structStudent{string name;intage;};// 用 const 引用避免拷贝voidprintStudent(constStudent&s){cout<<s.name<<" "<<s.age<<"岁"<<endl;}// 用指针修改结构体voidbirthday(Student*s){s->age++;// -> 通过指针访问成员}intmain(){Student stu={"赵六",22};printStudent(stu);// 赵六 22岁birthday(&stu);// 传地址printStudent(stu);// 赵六 23岁// 结构体指针Student*p=&stu;cout<<"(*p).age = "<<(*p).age<<endl;// 23cout<<"p->age = "<<p->age<<endl;// 23return0;}

二、枚举 enum

2.1 C 风格枚举

#include<iostream>usingnamespacestd;// 定义枚举类型enumColor{RED,GREEN,BLUE};// 默认 0, 1, 2enumWeekday{MON=1,TUE,WED};// 指定起始 1, 2, 3intmain(){Color c=GREEN;cout<<"GREEN = "<<GREEN<<endl;// 1cout<<"BLUE = "<<BLUE<<endl;// 2cout<<"TUE = "<<TUE<<endl;// 2// 枚举参与运算(隐式转 int)intvalue=c+1;cout<<"value = "<<value<<endl;// 2return0;}

2.2 enum class(C++11,推荐)

#include<iostream>usingnamespacestd;// 强类型枚举:必须用 类型::值 访问,不能隐式转 intenumclassColor{RED,GREEN,BLUE};enumclassLight{RED,YELLOW,GREEN};intmain(){Color c=Color::GREEN;Light l=Light::RED;// 类型安全:不同枚举类型可同名// int x = c; // 错误!不能隐式转 intintx=static_cast<int>(c);// 显式转换cout<<"GREEN = "<<x<<endl;// 1// 可比较(同类型)if(c==Color::GREEN){cout<<"是绿色"<<endl;}return0;}

2.3 两种枚举对比

维度enumenum class
作用域值注入外层命名空间值限定在类型内
类型安全可隐式转 int禁止隐式转换
同名冲突易冲突可同名
推荐程度不推荐推荐

三、类 class 初探

3.1 类与结构体的关系

#include<iostream>#include<string>usingnamespacestd;// struct 默认成员是 publicstructPoint{intx;inty;};// class 默认成员是 privateclassCircle{public:// 显式声明 publicdoubleradius;doublearea(){// 成员函数return3.14159*radius*radius;}};intmain(){Point p;// struct:直接访问p.x=10;Circle c;c.radius=5;cout<<"面积 = "<<c.area()<<endl;// 78.5398return0;}

3.2 完整的类定义

#include<iostream>#include<string>usingnamespacestd;classBankAccount{private:// 私有:外部不可直接访问string owner;doublebalance;public:// 公有:对外接口// 构造函数:对象创建时自动调用BankAccount(string name,doubleinitial){owne r=name;balance=initial;cout<<"账户创建: "<<owner<<endl;}// 成员函数(方法)voiddeposit(doubleamount){if(amount>0){balance+=amount;cout<<"存入 "<<amount<<" 元"<<endl;}}boolwithdraw(doubleamount){if(amount>0&&amount<=balance){balance-=amount;cout<<"取出 "<<amount<<" 元"<<endl;returntrue;}cout<<"余额不足!"<<endl;returnfalse;}voidshowBalance()const{// const 成员函数:不修改对象cout<<owner<<" 的余额: "<<balance<<" 元"<<endl;}};intmain(){BankAccountacc("小明",1000.0);acc.showBalance();// 小明 的余额: 1000 元acc.deposit(500);acc.showBalance();// 余额: 1500 元acc.withdraw(2000);// 余额不足acc.withdraw(300);// 取出 300 元acc.showBalance();// 余额: 1200 元// acc.balance = 0; // 错误!private 成员外部不可访问return0;}

3.3 访问控制总结

访问级别类内派生类外部
public
protected
private

封装原则:数据成员设为 private,通过 public 成员函数访问,保护数据安全。

四、构造函数与析构函数

4.1 构造函数

#include<iostream>usingnamespacestd;classRectangle{private:doublewidth;doubleheight;public:// 默认构造Rectangle(){width=0;height=0;cout<<"默认构造"<<endl;}// 带参构造Rectangle(doublew,doubleh){width=w;height=h;cout<<"带参构造: "<<w<<"x"<<h<<endl;}// 初始化列表(推荐,更高效)Rectangle(doubleside):width(side),height(side){cout<<"正方形构造"<<endl;}doublearea(){returnwidth*height;}};intmain(){Rectangle r1;// 默认构造Rectangler2(3,4);// 带参构造Rectangler3(5);// 正方形构造cout<<"r1 面积: "<<r1.area()<<endl;// 0cout<<"r2 面积: "<<r2.area()<<en dl;// 12cout<<"r3 面积: "<<r3.area()<<endl;// 25return0;}

4.2 析构函数

#include<iostream>usingnamespacestd;classResource{public:Resource(){cout<<"资源创建"<<endl;}// 析构函数:对象销毁时自动调用,用于释放资源~Resource(){cout<<"资源释放"<<endl;}};intmain(){cout<<"main 开始"<<endl;{Resource res;// 构造cout<<"使用资源..."<<endl;}// 离开作用域,析构cout<<"main 结束"<<endl;return0;}

输出顺序:

main 开始 资源创建 使用资源... 资源释放 main 结束

五、实战:学生信息登记系统

综合本篇知识,用结构体 + 类实现学生登记:

#include<iostream>#include<string>usingnamespacestd;// 结构体:基础数据structStudent{string name;intage;doublescore;};// 类:管理学生集合classStudentManager{private:Student students[100];// 最多 100 人intcount;public:StudentManager():count(0){}voidaddStudent(string name,intage,doublescore){if(count>=100){cout<<"人数已满!"<<endl;return;}students[count]={name,age,score};count++;cout<<"已添加: "<<name<<endl;}voidprintAll()const{cout<<"===== 学生名单 ====="<<endl;for(inti=0;i<count;i++){cout<<i+1<<". "<<students[i].name<<" "<<students[i].age<<"岁 "<<students[i].score<<"分"<<endl;}}doubleaverageScore()const{if(count==0)return0;doublesum=0;for(inti=0;i<count;i++){sum+=students[i].score;}returnsum/count;}};intmain(){StudentManager manager;manager.addStudent("张三",20,88.5);manager.addStudent("李四",21,92.0);manager.addStudent("王五",19,76.5);manager.printAll();cout<<"平均分: "<<manager.averageScore()<<endl;return0;}

运行示例:

已添加: 张三 已添加: 李四 已添加: 王五 ===== 学生名单 ===== 1. 张三 20岁 88.5分 2. 李四 21岁 92分 3. 王五 19岁 76.5分 平均分: 85.6667

总结

本篇讲解了结构体 struct(定义/数组/指针传参)、枚举 enum 与 enum class 的区别、类 class 的基本语法(成员/方法/访问控制)、构造函数与析构函数,并用学生信息登记系统串联实战。重点掌握:struct 与 class 的区别、enum class 的类型安全、public/private 封装思想、构造与析构时机。

下一篇将深入讲解类与对象(深拷贝/浅拷贝、static 成员、this 指针、友元),敬请期待!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/30 15:19:46

长表格核对技巧:冻结窗格固定首行尾行,打印每页带标题

长表格核对数据时&#xff0c;最烦的不是数据量大&#xff0c;而是滚两下就忘了哪一列是哪一项。首行标题滚出屏幕后&#xff0c;整张表几乎没法看&#xff1b;如果底部还有合计行&#xff0c;拉到末尾又忘了上面汇总的字段顺序。来回拖动滚动条&#xff0c;两个人对着一张表反…

作者头像 李华
网站建设 2026/8/30 15:16:06

从超级循环到FreeRTOS:嵌入式任务架构设计与通信机制深度解析

很多嵌入式开发者接触 FreeRTOS 之后&#xff0c;第一件事就是移植、建任务、看调度器跑起来。这当然没错&#xff0c;但真正的问题往往在后面&#xff1a;FreeRTOS 跑得挺顺&#xff0c;程序结构却还是超级循环的思路。标志位满天飞、全局变量随手就建、互斥量见一个加一个&am…

作者头像 李华
网站建设 2026/8/30 15:06:22

模拟器坍塌:多智能体强化学习泛化失败的隐形元凶

我们经常遇到一类很让人困惑的强化学习实验&#xff1a;在训练环境里&#xff0c;智能体的奖励曲线一路上扬&#xff0c;收敛速度和最终分数都很漂亮&#xff1b;可一旦把模型放到新的模拟器、新的对手或者略有变化的业务环境里&#xff0c;效果立刻“打回原形”&#xff0c;奖…

作者头像 李华