C++ 类的 static 成员函数

我用最简单、最直观、和你代码一模一样的场景 ,给你把 static 讲得明明白白!

先记一句话

普通成员 = 属于某个对象(每个传感器自己的) 静态成员 = 属于整个类(大家共用的)


1. 普通成员函数(不带 static)

cpp

运行

复制代码
class SensorSht40 {
    void ReadTask(void *arg); 
};

特点:

  1. 属于某一个传感器对象
  2. 必须通过 sensor->ReadTask() 调用
  3. 自带 this 指针(知道自己是哪个传感器)
  4. 能直接访问私有变量 _temperature

cpp

运行

复制代码
SensorSht40 sensor1;
SensorSht40 sensor2;

sensor1.ReadTask(); // 是 sensor1 的
sensor2.ReadTask(); // 是 sensor2 的

2. 静态成员函数(带 static)

cpp

运行

复制代码
class SensorSht40 {
    static void readTaskWrapper(void *arg);
};

特点:

  1. 不属于任何传感器!属于整个类
  2. 没有 this 指针
  3. 可以直接调用,不需要对象
  4. 能访问私有成员

cpp

运行

复制代码
// 直接用类调用,不需要传感器对象!
SensorSht40::readTaskWrapper(arg);

3. 为什么 FreeRTOS 必须用 static?

FreeRTOS 创建任务要求函数格式必须是:

cpp

运行

复制代码
void (*task_fn)(void *arg);

普通成员函数,编译器会变成:

cpp

运行

复制代码
void ReadTask(SensorSht40* this, void *arg);

❌ 多了一个 this → 格式不匹配 → 报错!

静态函数编译器就是:

cpp

运行

复制代码
void readTaskWrapper(void *arg);

✅ 完全匹配 → 可以创建任务!


4. 最经典的例子(你代码里的用法)

任务包装函数 必须 static

cpp

运行

复制代码
class SensorSht40 {
private:
    float _temperature;

    // 真正的任务(每个传感器自己的)
    void ReadTask(void *arg) {
        while(1) {
            _temperature = read();
            vTaskDelay(1000);
        }
    }

    // 👇 静态包装函数(通用,无this)
    static void readTaskWrapper(void *arg) {
        SensorSht40* sensor = (SensorSht40*)arg;
        sensor->ReadTask(); // 调用真正的任务
    }
};

创建任务

cpp

运行

复制代码
xTaskCreate(readTaskWrapper, ..., this, ...);

流程:

  1. 任务启动 → 调用 readTaskWrapper
  2. 它是 static → 符合 FreeRTOS 要求
  3. 从 arg 拿到传感器对象
  4. 调用真正的 sensor->ReadTask()

5. 静态变量例子(共用数据)

cpp

运行

复制代码
class SensorSht40 {
    static int sensor_count;
};

// 所有传感器共用一个 count
SensorSht40 s1;
SensorSht40 s2;

s1.count = 1;
s2.count = 2; 
// s1.count 也变成 2!

6. 超级总结(3 句话背会)

  1. static 成员属于类,不属于对象
  2. static 函数没有 this 指针 → 能当 FreeRTOS 任务
  3. static 函数能访问 private → 完美封装

对应你现在的代码

cpp

运行

复制代码
static void readTaskWrapper(void *arg);

这就是 C++ + FreeRTOS 最标准、最安全、最正确的写法

如果你愿意,我可以给你一个万能模板,以后所有传感器、电机、屏幕类都能直接复制使用!

相关推荐
ysa05103026 分钟前
【板子】德州扑克模拟
c++·笔记·板子
慧都小项44 分钟前
C/C++ 静态分析为什么要前移?Parasoft C/C++test 在 IDE 与 CI/CD 中的应用
c语言·c++·ide·功能测试·ai
qq_33776320191 小时前
国际期货资管系统开发方案|内外盘交易平台源码授权与二次开发支持
java·c语言·开发语言·c++·c#
zmzb010312 小时前
C++课后习题训练记录Day157
开发语言·c++
从零开始的代码生活_16 小时前
C++ 多态详解:虚函数、动态绑定、抽象类与虚表原理
开发语言·c++·后端·学习·算法
大彼方..16 小时前
C++ STL Vector 深度剖析:从内存管理到性能优化
开发语言·c++
炸薯条!17 小时前
从零开始学C++ (内存管理)
java·jvm·c++
cpp_250118 小时前
P6625 [省选联考 2020 B 卷] 卡牌游戏
数据结构·c++·算法·前缀和·贪心·洛谷题解·省选
旖-旎21 小时前
《LeetCode 416 分割等和子集》
c++·算法·leetcode·动态规划·背包问题
Mortalbreeze21 小时前
深入理解 Linux 线程机制(四):线程同步——条件变量与信号量
linux·运维·服务器·开发语言·c++