【问题标题】:Declaration of global members inside a class in c++在 C++ 中的类中声明全局成员
【发布时间】:2019-12-04 15:47:35
【问题描述】:

我正在尝试对微控制器进行编程以移动电机并使用编码器和一些电位计执行其他功能。我想使用一个通过脉冲宽度调制信号向电机驱动器发送脉冲的库,但据我了解,这个库的类依赖于静态变量,我不知道如何从我自己的类中访问这些变量。这是我的标题的简化:

#include <Arduino.h>
#include <Teensystep.h>
#define startStop               2
#define stepPin                 3
#define dirPin                  4
#define channelA                5
#define channelB                6
#define enabPin                 7
#define dirSwitch               8
#define soundTrig               9
#define chipSelect              10
#define mosiSdi                 11
#define misoSdo                 12
#define clk                     13

#define led                     A3
#define potSpeed                A4
#define encoButton              A5
#define sensor                  A7

class Example{

public:  

        void moveMotor();

};

这将是我的 example.cpp,我在其中使用电机和控制器,它们是全局对象:


#include <example.h>

void Example::moveMotor(){

    ::motor.setTargetRel(1024);
    ::controller.move(::motor);
}

这是我的 main.cpp 文件:

#include <example.h>

  Stepper motor(stepPin, dirPin);
  StepControl controller;
  Example exampleObject();

void setup(){

  pinMode(enabPin, OUTPUT);
  pinMode(stepPin, OUTPUT);
  pinMode(chipSelect, OUTPUT);
  pinMode(dirPin, OUTPUT);
  pinMode(sensor, INPUT_PULLUP);
  pinMode(led, OUTPUT);
  pinMode(channelA, INPUT);
  pinMode(channelB, INPUT);
  pinMode(startStop, OUTPUT);
  pinMode(dirSwitch, OUTPUT);
  pinMode(encoButton, INPUT);

};

void loop(){
   exampleObject.moveMotor();
};

我知道我做错了,但我不知道在哪里寻找解决方案,欢迎任何帮助。谢谢。

在上述文件中,我创建了一个名为Example 的类,它只有一个函数依赖于两个对象,StepperStepControl。这两个对象必须全局声明,因为它们具有静态成员。出于这个原因,我正在编写调用全局对象的类的函数:


#include <example.h>

void Example::moveMotor(){

    ::motor.setTargetRel(1024);
    ::controller.move(::motor);
}

但是,当我编译程序时,编译器告诉我

'motor' has not been declared. The global scope has no 'motor'

如何使类的成员成为全局对象?

我正在用 Visual Code for linux 编写程序,它带有一个名为 platformIO 的物理计算扩展,我正在使用的库名为 TeensyStep

【问题讨论】:

  • 不相关:标题中的#defines 块看起来很像您应该考虑将其设为enum
  • @user4581301 非常感谢您的建议。你能解释一下为什么在这种情况下enum#define 更好吗?
  • #define 是一个简单的文本替换,它发生在几乎所有其他内容之前。没有对替换应用健全性检查或更智能的逻辑。在代码中找到startStop 的任何地方都将其替换为2,无论替换多么愚蠢或疯狂。如果您不小心重用了startStop,例如函数void startStop(),结果可能真的很奇怪,编译器将前面的函数视为void 2(),错误消息几乎总是具有误导性。 enum 在编译期间进行处理,并在使用前进行更彻底的检查。

标签: c++ class forward-declaration scopes


【解决方案1】:

你的前提被打破了:

这两个对象必须全局声明,因为它们有静态成员。

没有。当一个类具有静态成员时,您实际上不需要任何对象来访问这些成员。

不清楚您在哪里声明了Stepper,但是当您尝试访问其成员时,您似乎缺少#include。如果setTargetRel()staticStepper 方法,那么您可以这样称呼它:

 Stepper::setTargetRel(1024);

如果setTargetRel 不是静态方法,那么您需要一个实例来调用它。您仍然不应该将此实例设为全局变量,而是将其设为 Example 的成员或将其作为参数传递给 Example::moveMotor

【讨论】:

  • 非常感谢您的回答,我会尽快尝试。所以,如果我理解正确的话,可以用Stepper::setTargetRel() 调用成员setTargetRel 而无需创建Stepperobject?
  • @AntonioCastles 我不知道。如果是静态方法,那么是的
【解决方案2】:

添加到example.h:
extern Stepper motor;

添加到example.cpp:
Stepper motor(stepPin, dirPin);

void Example::moveMotor() {
    motor.setTargetRel(1024); // remove :: before motor

main.cpp删除:
Stepper motor(stepPin, dirPin);

这应该允许包括example.h 在内的所有文件使用全局变量motor - 但整体设计有问题。

如果Example 负责设置目标和初始化动作,为什么它不同时拥有StepperStepControl 实例并提供方便的函数来将动作保持在一起?示例:

class Example {
public:
  Example() : 
    motor(stepPin, dirPin),
    controller{}
  {}  

  void moveMotor(int target=1024) {
    motor.setTargetRel(target);
    controller.move(motor);
  }

private:
  Stepper motor;
  StepControl controller;
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-22
    • 1970-01-01
    • 2012-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-20
    相关资源
    最近更新 更多