You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过指针读取类变量,实现旋转编码器位置值同步?

嘿,我完全get到你的需求了——就是让旋转编码器切换控制不同类变量时,能自动把编码器的起始位置对齐到该变量之前的取值,之后用户调整编码器时,直接修改对应的类变量对吧?结合你想用指针传递参数的思路,我给你整理一套清晰的实现方案:

核心思路拆解

要实现这个功能,关键要做到两点:

  • 用指针关联编码器和当前要控制的类变量,让编码器能直接读写这个变量
  • 每次切换控制的类变量时,把编码器的当前位置同步为该变量的历史值,这样后续调整就从这个值开始

具体代码实现

首先先定义你的设置类,里面包含需要用编码器控制的变量:

class DeviceSettings {
public:
    int screenBrightness = 50;  // 初始亮度50
    int speakerVolume = 30;     // 初始音量30
    int displayContrast = 70;   // 初始对比度70
};

接下来,我们需要管理编码器的状态,以及当前控制的目标变量:

// 旋转编码器的当前位置(用来同步类变量的值)
int encoderCurrentPos = 0;
// 指向当前正在控制的类变量的指针
int* activeTargetVar = nullptr;

然后写两个核心函数:一个用来切换控制的目标变量,另一个处理编码器的转动逻辑:

// 切换到目标类变量,同步编码器起始位置
void switchToControlVariable(int* targetVar) {
    if (!targetVar) return; // 防止空指针
    // 把编码器位置对齐到目标变量的当前值(历史值)
    encoderCurrentPos = *targetVar;
    // 更新当前控制的变量指针
    activeTargetVar = targetVar;
}

// 处理编码器转动,修改目标变量的值
void processEncoderRotation(int delta) {
    if (!activeTargetVar) return; // 还没选中目标,直接返回
    
    // 更新编码器位置
    encoderCurrentPos += delta;
    // 给变量加个范围限制(比如0-100,根据你的需求调整)
    encoderCurrentPos = std::max(0, std::min(encoderCurrentPos, 100));
    // 把编码器位置同步给目标类变量
    *activeTargetVar = encoderCurrentPos;
}

实际使用示例

int main() {
    DeviceSettings myDeviceSettings;

    // 第一次切换到控制亮度:编码器起始位置自动设为50
    switchToControlVariable(&myDeviceSettings.screenBrightness);
    // 编码器顺时针转10格,亮度变为60
    processEncoderRotation(10);

    // 切换到控制音量:编码器起始位置自动设为30(初始值)
    switchToControlVariable(&myDeviceSettings.speakerVolume);
    // 编码器逆时针转5格,音量变为25
    processEncoderRotation(-5);

    // 切回控制亮度:编码器起始位置自动设为60(之前修改后的历史值)
    switchToControlVariable(&myDeviceSettings.screenBrightness);
    // 编码器再转5格,亮度变为65
    processEncoderRotation(5);

    return 0;
}

优化:封装成类(更符合面向对象设计)

如果你的项目更复杂,建议把编码器的逻辑封装成一个独立的类,这样代码更整洁:

class EncoderController {
private:
    int encoderPos = 0;
    int* currentTarget = nullptr;
    int minVal = 0;
    int maxVal = 100;

    // 辅助函数:限制数值范围
    int clamp(int val) {
        return val < minVal ? minVal : (val > maxVal ? maxVal : val);
    }

public:
    // 切换目标变量,同步起始位置
    void setTargetVariable(int* target) {
        if (!target) return;
        encoderPos = *target;
        currentTarget = target;
    }

    // 处理转动
    void rotate(int delta) {
        if (!currentTarget) return;
        encoderPos += delta;
        encoderPos = clamp(encoderPos);
        *currentTarget = encoderPos;
    }

    // 可以自定义范围
    void setRange(int min, int max) {
        minVal = min;
        maxVal = max;
    }
};

// 使用封装后的类
int main() {
    DeviceSettings mySettings;
    EncoderController encoder;

    encoder.setTargetVariable(&mySettings.screenBrightness);
    encoder.rotate(10); // 亮度变为60

    encoder.setTargetVariable(&mySettings.speakerVolume);
    encoder.rotate(-5); // 音量变为25

    return 0;
}

对你最初代码的小修正

你之前写的void Function(int (*Argument))是定义了一个接收函数指针的参数,但我们需要的是接收类变量的指针,所以应该改成void Function(int* Argument),这样才能正确指向类的成员变量,实现读写操作。

内容的提问来源于stack exchange,提问作者Cammack

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:53:53