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 最标准、最安全、最正确的写法

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

相关推荐
天若有情6736 小时前
C++花式魔改!手写头文件复刻Java语法,彻底打破编码思维定式
java·c++·语言做语言·jac++
qq_199886877 小时前
第7板块·第3节:CUTLASS 的 GEMM 实现与优化策略
c++·人工智能·gpu算力·cuda
hetao17338377 小时前
2026-09-17 hetao1733837 的刷题记录
c++·算法
shada8 小时前
Boost.Process v2 在旧内核上报 `assign: Bad file descriptor`
c++
别动我齐刘海8 小时前
ROS2 Jazzy + C++ 实战路线——基础学习2
c++·人工智能·vscode·python·学习·机器学习·机器人
朝朝辞暮i9 小时前
C++第 2 课
c++
代码中介商10 小时前
C++ 预约系统实战(三):服务端实现——libevent 事件驱动与业务路由
c++·json·c/s
布莱克60511 小时前
C++中的内存分区详解
c++
All for pursuit.11 小时前
【链表-9】146.LRU缓存
数据结构·c++·算法·leetcode
j7~12 小时前
【C++微服务项目开发脚手架】(接口篇一)gflags + gtest + spdlog 接口学习笔记
c++·学习·gtest·项目开发·spdlog·gflags·c++项目微服务开发脚手架