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

C++核心编程:类与对象全面解析

C++核心编程:类与对象全面解析

大家好!今天我要和大家深入探讨C++面向对象编程中最核心的概念:类与对象。👨‍💻 这是我们迈向高级C++开发的第一步,掌握好这部分内容,对未来学习更高级的设计模式和框架都至关重要!

📚 嵌入式开发爱好者必看:如果你对嵌入式开发感兴趣,我强烈推荐查看 FreeRTOS + STM32 学习资源库,里面包含从入门到精通的详细教程和实例代码!

📋 学习目标

  1. 理解类和类的成员的概念,掌握声明类的方法,以及由类定义对象的方法
  2. 初步掌握用类和对象编写基于对象的程序
  3. 学会检查和调试基于对象的程序
  4. 掌握类的构造函数和析构函数的定义
  5. 掌握对象数组、对象指针及其使用方法
  6. 掌握共用数据的保护方法

🔍 经典程序剖析

1. 构造函数与析构函数执行顺序分析

先阅读下面的程序,尝试预测运行结果,然后再验证:

构造函数与析构函数示例

#include <iostream>
using namespace std;
class A {
public:A() {cout << "Constructing A" << endl;}~A() {cout << "Destructing A" << endl;}
};class B {
public:B() {cout << "Constructing B" << endl;}~B() {cout << "Destructing B" << endl;}
};int main() {A a;B b;return 0;
}

代码分析

  • 这段程序展示了构造函数和析构函数的调用顺序
  • 对象创建时,构造函数按照定义顺序执行(先A后B)
  • 对象销毁时,析构函数按照与创建相反的顺序执行(先B后A)
  • 这遵循了C++中"后进先出"的内存管理原则

🔥 实时系统编程提示:在嵌入式实时系统如FreeRTOS中,理解对象生命周期对于避免内存泄漏和系统崩溃至关重要。查看 FreeRTOS资源库 了解更多内存管理技巧!

2. 拷贝构造函数深入理解

拷贝构造函数示例

#include<iostream>
using namespace std;class Test
{int x, y;  
public:Test(int i, int j) {x = i;  y = j;  cout << "con\n";  }Test(Test &A) {  x = A.x;    y = A.y;cout << "copycon\n";}void show() {cout << "x=" << x << "\t y=" << y << endl; }
};int main()
{Test B1(2, 3); Test B2 = B1;   Test B3(B1);    B2.show();      B3.show();return 0;    
}

代码分析

  • 这个例子展示了拷贝构造函数的两种调用方式
  • Test B1(2, 3) 调用普通构造函数
  • Test B2 = B1Test B3(B1) 都调用拷贝构造函数
  • 拷贝构造函数用于创建一个新对象,该对象是现有对象的副本
  • 注意拷贝构造函数的参数是引用类型,这是必须的,否则会导致无限递归

3. 对象数组与对象指针运用

对象数组与指针示例

#include <iostream>
using namespace std;class Sample {int x;
public:void setx(int i) {x = i;    }int putx() {return x; }
};int main() {Sample *p;            Sample A[3];         A[0].setx(5);A[1].setx(6);A[2].setx(7);for(int j=0; j<3; j++) {  p = &A[j];      cout << p->putx() << " ";  }cout << endl;return 0;           
}

代码分析

  • 此程序展示了对象数组与对象指针的基本使用
  • Sample A[3] 创建了一个包含3个Sample对象的数组
  • 通过数组下标访问每个对象并设置其x成员
  • 使用指针p依次指向数组中的每个对象
  • 通过指针使用->运算符调用成员函数

💡 嵌入式开发技巧:在资源受限的嵌入式系统中,对象数组和指针操作的效率尤为重要。在 FreeRTOS项目 中有很多实际应用案例!

🛠️ 程序调试与优化

1. 构造函数声明修复

原代码存在问题,现已修正:

构造函数修复

#include <iostream>
using namespace std;  class A {int i;
public:A(int ii) {      // 错误构造函数声明(void A→A)i = ii;}int geti() {     return i;}
};int main() {A *pa;           pa = new A(10);  // 补充(int参数)cout << "i=" << pa->geti() << endl;  return 0;         
}

问题分析

  • 原代码中构造函数声明错误,使用了void A而非A
  • 创建动态对象时缺少必要的构造函数参数
  • 修正后,动态创建对象并正确初始化,输出结果为i=10

2. 类成员访问修复

类成员访问修复

#include <iostream>
using namespace std;  class base {int x, y;        
public:int z;void Init(int a, int b) {  setx(a);sety(b);}int getx() { return x; }  int gety() { return y; }  void setx(int a) { x = a; }void sety(int b) { y = b; }
};  int main() {base A, B;        A.Init(76, 77);   B.Init(78, 79);    cout << "A.x=" << A.getx() << endl;cout << "B.x=" << B.getx() << endl;return 0;         
}

问题分析

  • 原代码直接访问私有成员xy导致错误
  • 修正后通过公有成员函数getx()访问私有成员
  • 这展示了封装原则的重要性:私有成员只能通过公有接口访问

3. 解决作用域解析问题

作用域解析修复

#include <iostream>       
using namespace std;class Time {
public:int hour, minute;void printTime();     void setHour(int h, int m) {hour = h;         minute = m;       }
};                      void Time::printTime() {  // 修正作用域解析cout << "hour: " << hour << "/minute: " << minute << endl; }int main() {Time aTime;           aTime.setHour(5, 39); aTime.printTime();    // 未指定对象 → 补全aTime.return 0;             
}

问题分析

  • 原代码中类外成员函数定义缺少作用域解析符Time::
  • main()中,成员函数调用缺少对象指定
  • 修复后正确输出:hour:5/minute:39

问题4

🔧 开发效率提升:良好的代码组织和作用域管理在复杂项目中尤为重要。查看 FreeRTOS项目 中的源码结构,学习专业的代码组织方式!

📝 程序填空题解析

1. 构造函数与访问器补全

构造函数与访问器

#include<iostream>
using namespace std;
class a
{
private:int num;float f1;
public:a();a(int n, double f);  // 填入参数类型 int n, double fint Getint(){return num;}    // 返回类型为 intdouble Getdouble(){return f1;} // 返回类型为 double(float自动提升)
};a::a()  // 类外构造函数定义
{cout<<"默认初始化"<<endl;num = 0;    // 初始化整型成员f1 = 0.0;   // 初始化浮点成员
}a::a(int n,double f)
{cout<<"初始化"<<endl;num=n;f1=f;
}int main()
{a x;a y(2,4.5);cout<<x.Getint()<<" "<<x.Getdouble()<<endl;cout<<y.Getint()<<" "<<y.Getdouble()<<endl;return 0 ;
}

填空解析

  1. 参数构造函数声明:a(int n, double f)
  2. 整型访问器返回类型:int
  3. 浮点访问器返回类型:double
  4. 默认构造函数定义:a::a()
  5. 整型成员初始化:num = 0
  6. 浮点成员初始化:f1 = 0.0

2. 三角形计算类实现

三角形计算

#include <iostream>  // 补全输入输出流头文件
#include <math.h>
using namespace std;
class A
{double a,b,c;
public:A (double,double,double);double fun1();     // 声明计算周长的成员函数double fun2();     // 声明计算面积的成员函数
};double A::fun1(){return a+b+c;}
A::A(double i,double j,double k)
{a=i;b=j;c=k;
}
double A::fun2()
{double d;d = (a+b+c) / 2.0;return sqrt(d*(d-a)*(d-b)*(d-c));
}int main()
{A a1(3,4,5);cout<<"三角形边长和:";cout << a1.fun1();  // 调用周长计算函数cout<<endl;cout<<"三角形面积:";cout << a1.fun2();  // 调用面积计算函数cout<<endl;return 0 ;
}

填空解析

  1. 包含头文件:#include <iostream>
  2. 周长计算函数声明:double fun1();
  3. 面积计算函数声明:double fun2();
  4. 输出周长:cout << a1.fun1();
  5. 输出面积:cout << a1.fun2();

📊 数学算法应用:像这样的几何计算在嵌入式系统中也很常见,特别是在传感器数据处理和位置计算中。FreeRTOS项目 中有许多实时数据处理的范例!

💻 实战编程挑战

1. 时钟类设计实现

时钟类效果
时钟类运行效果

#include <iostream>
#include <iomanip>  // 用于格式化输出
using namespace std;class Clock {
private:int hour;int minute;int second;public:// (1) 构造函数:默认初始化00:00:00Clock() : hour(0), minute(0), second(0) {}// (1) 重载构造函数:指定时分秒Clock(int h, int m, int s) : hour(h), minute(m), second(s) {}// (2) 动态设置时间void setclock(int h, int m, int s) {hour = h;minute = m;second = s;}// (3) 格式化显示时间void showclock() {cout << setfill('0')  // 不足两位补零<< setw(2) << hour << ":" << setw(2) << minute << ":" << setw(2) << second << endl;}
};int main() {Clock clock1;                   // 默认构造clock1.showclock();             // 输出 00:00:00clock1.setclock(12, 1, 1);      // 动态设置时间clock1.showclock();             // 输出 12:01:01Clock clock2(13, 1, 1);         // 指定参数构造clock2.showclock();             // 输出 13:01:01return 0;
}

实现重点

  • 使用私有数据成员保护时间数据
  • 提供两种构造函数实现不同的初始化方式
  • 使用setfillsetw确保时间格式的标准化(两位数字,不足前补0)
  • 提供设置时间的公有接口,保持封装性

⏱️ 实时性提示:在实时系统中,时间管理至关重要。FreeRTOS提供了专门的时间管理函数和延时机制,详见 FreeRTOS资源库 中的时间管理部分!

2. 图书管理系统实现

图书管理系统效果
图书管理系统运行效果

#include <iostream>
#include <string>
using namespace std;class Book {
private:string bookname;double price;int number;public:// 构造函数初始化数据成员Book(string name, double p, int num) : bookname(name), price(p), number(num) {}void display() {cout << "书名:" << bookname << endl<< "价格:" << price << "元" << endl<< "库存:" << number << "本" << endl;}void borrow() {if(number > 0) {number--;cout << "借阅成功,当前库存:" << number << endl;} else {cout << "库存不足,无法借阅!" << endl;}}void restore() {number++;cout << "归还成功,当前库存:" << number << endl;}
};int main() {// 创建图书对象Book book1("C++", 23.5, 3);Book book2("Data Structure", 28.8, 7);// 操作book1cout << "----book1信息----" << endl;book1.display();book1.borrow();book1.borrow();book1.restore();// 操作book2cout << "\n----book2信息----" << endl;book2.restore(); book2.display();  return 0;
}

实现重点

  • 使用私有成员保存图书信息,体现封装原则
  • 构造函数使用初始化列表高效初始化
  • borrow()方法加入库存检查,防止出现负数库存
  • 清晰的UI设计使用户交互更直观

📚 系统设计拓展:这个简单的图书管理系统体现了面向对象编程的基本原则。在真实的嵌入式系统中,类似的资源管理更为复杂,需要考虑并发访问、资源锁定等问题。这些问题在 FreeRTOS项目 中有详细讲解和示例!

📌 总结与拓展

通过本文的学习,我们掌握了C++类与对象的核心概念:

  1. 类的定义与对象的创建
  2. 构造函数与析构函数的使用
  3. 拷贝构造函数的特性
  4. 对象数组与对象指针的操作
  5. 封装和数据保护

这些概念是深入理解C++的基础,也是进阶到更复杂系统设计的垫脚石。想更深入学习嵌入式开发和实时操作系统?请访问 Despacito0o的FreeRTOS学习资源库,那里有从入门到精通的全套资源!

🚀 学习建议:如果你掌握了本文的内容,推荐接下来学习C++的继承和多态特性,以及模板编程。这些高级特性将使你的代码更加灵活和强大!

http://www.xdnf.cn/news/192817.html

相关文章:

  • Infrared Finance:Berachain 生态的流动性支柱
  • 车载软件架构 --- AUTOSAR的方法论
  • SwiftUI 8.List介绍和使用
  • 零基础制作Freertos智能小车(教程非常简易)持续更新中....
  • DeepSeek创始人梁文峰是个什么样的人?
  • LLM - Large Language Model
  • Android Studio 中使用 SQLite 数据库开发完整指南(Kotlin版本)
  • Redis最佳实践
  • nginx代理websocket时ws遇到仅支持域名访问的处理
  • 23种设计模式 -- 工厂模式
  • 算力困局:AI 狂飙背后的能源枷锁与破局之道
  • 后端[特殊字符][特殊字符]看前端之Row与Col
  • 1.9多元函数积分学
  • Day15(贪心算法)——LeetCode121.买卖股票的最佳时机55.跳跃游戏
  • 【计网】计算机网络的类别与性能
  • Rust 学习笔记:修复所有权常见错误
  • cookie和session
  • Flink Checkpoint 与实时任务高可用保障机制实战
  • DBeaver详细安装步骤
  • 【AI】【MCP】搭建私人王炸MCP自动化工作流
  • 微信jdk 前端vue获取流程1、
  • 泰迪杯实战案例超深度解析:特殊医学用途配方食品数据分析与智能推荐系统设计
  • 《Linux篇》基础开发工具——vim详细介绍
  • 使用手机录制rosbag包
  • 21.气体放电管的特性与使用注意事项
  • uniapp+vue3+ts 使用canvas实现安卓端、ios端及微信小程序端二维码生成及下载
  • 十一、引用与拷贝函数(References the Copy-Constructor)
  • C++实时统计数据均值、方差和标准差
  • WGCAT工单系统发现错误 定时处理工单数据任务错误
  • MySQL笔记-mysql -hlocalhost和mysql -h127.0.0.1的不同