如何通过指针读取类变量,实现旋转编码器位置值同步?
嘿,我完全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
相关产品推荐
相关产品推荐

