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

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

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

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

📋 学习目标

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

🔍 经典程序剖析

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

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

cpp 复制代码
#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. 拷贝构造函数深入理解

cpp 复制代码
#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. 对象数组与对象指针运用

cpp 复制代码
#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. 构造函数声明修复

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

cpp 复制代码
#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. 类成员访问修复

cpp 复制代码
#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. 解决作用域解析问题

cpp 复制代码
#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

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

📝 程序填空题解析

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

cpp 复制代码
#include<iostream>
using namespace std;
class a
{
private:
    int num;
    float f1;
public:
    a();
    a(int n, double f);  // 填入参数类型 int n, double f
    int Getint(){return num;}    // 返回类型为 int
    double 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. 三角形计算类实现

cpp 复制代码
#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. 时钟类设计实现


cpp 复制代码
#include <iostream>
#include <iomanip>  // 用于格式化输出
using namespace std;

class Clock {
private:
    int hour;
    int minute;
    int second;

public:
    // (1) 构造函数:默认初始化00:00:00
    Clock() : 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:00
    
    clock1.setclock(12, 1, 1);      // 动态设置时间
    clock1.showclock();             // 输出 12:01:01
    
    Clock clock2(13, 1, 1);         // 指定参数构造
    clock2.showclock();             // 输出 13:01:01
    
    return 0;
}

实现重点

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

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

2. 图书管理系统实现


cpp 复制代码
#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);

    // 操作book1
    cout << "----book1信息----" << endl;
    book1.display();
    book1.borrow();
    book1.borrow();
    book1.restore();

    // 操作book2
    cout << "\n----book2信息----" << endl;
    book2.restore(); 
    book2.display();  

    return 0;
}

实现重点

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

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

📌 总结与拓展

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

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

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

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

相关推荐
__lost31 分钟前
MATLAB画出3d的常见复杂有机分子和矿物的分子结构
开发语言·人工智能·matlab·化学·分子结构
mozun20202 小时前
VS BUG(6) LINK : fatal error LNK1158: 无法运行“rc.exe”
c++·bug·vs·链接器·资源文件
夜夜敲码2 小时前
C语言教程(十八):C 语言共用体详解
c语言·开发语言
大学生亨亨2 小时前
go语言八股文(五)
开发语言·笔记·golang
raoxiaoya2 小时前
同时安装多个版本的golang
开发语言·后端·golang
whoarethenext3 小时前
初始https附带c/c++源码使用curl库调用
服务器·c++·qt·https·curl
cloues break.4 小时前
C++进阶----多态
开发语言·c++
我不会编程5554 小时前
Python Cookbook-6.10 保留对被绑定方法的引用且支持垃圾回收
开发语言·python
道剑剑非道4 小时前
QT开发技术【qcustomplot 曲线与鼠标十字功能】
开发语言·qt·计算机外设
刘婉晴4 小时前
【环境配置】Mac电脑安装运行R语言教程 2025年
开发语言·macos·r语言