当前位置: 首页 > news >正文

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 指针、友元),敬请期待!

http://www.cnnetsun.cn/news/4309925.html

相关文章:

  • 长表格核对技巧:冻结窗格固定首行尾行,打印每页带标题
  • 从超级循环到FreeRTOS:嵌入式任务架构设计与通信机制深度解析
  • Yuki第012个开关:阻止仅看一次销毁的位置、验证方法与发送者意图边界
  • Yuki第011个开关:消息时间标签显示的位置、验证方法与时间可读性边界
  • 抖助手第022个开关:好友交换作弊的位置、证据边界与安全测试原则
  • 模拟器坍塌:多智能体强化学习泛化失败的隐形元凶
  • BiTAgent: A Task-Aware Modular Framework for Bidirectional Coupling between Multimodal Large Lang...
  • 2016电商后端笔试题复盘:从算法到系统设计的核心考点解析
  • 不安全代码上线前的配置检查
  • 游戏后端Java笔试复盘:非游戏基础题考点全解析
  • Dify搭建Agent工作流:从本地部署到客服工单自动化实战
  • Windows端口转发不生效?IP Helper服务、防火墙、注册表三步排查
  • 2023大厂Java面试八股文核心考点全解析:从HashMap到分布式锁
  • Windows11专业版使用虚拟化技术安装Linux(CentOS7)
  • 用AI让AI更聪明:最小Agent的四大关键工程实践
  • GradCuit:信用分配梯度流如何增强大模型潜在空间推理
  • ComfyUI工作流从零搭建:从文生图到AI视频生成全攻略
  • CAD 2027零基础入门:安装、画图到出图全流程避坑指南
  • DeepSeek V4 Flash 接入 Codex 完整指南:配置、API Key与报错排查
  • Wasserstein距离度量下的ULA混合时间测量与Python实验
  • 中段面试制胜指南:二面三面与HR面全攻略
  • STM32U3 USBX设备开发:HAL PCD初始化“缺失”的真相与排查
  • Dubbo面试八股文:服务暴露、Nacos适配与性能调优全解析
  • Adapter+持续学习:恶意流量识别少样本增量更新的新思路
  • Goose AI Agent 入门指南:10 分钟装好跑通第一次会话,MCP 扩展 70+ 外部工具
  • 英伟达拟收购Hugging Face:AI模型分发与GPU推理生态将如何重塑
  • Starship 提示符 5 分钟上手:3 行配置改出你自己的终端提示符
  • BT 公共 Tracker 列表上手指南:选列表、配 qBittorrent、验证效果
  • 如何搭建 Gitea Actions 自动化流水线
  • OBS Studio 免费直播录制教程:从零搭场景到稳定开播