【问题标题】:Arduino - How to increment a (inherited) public Class member with pointers?Arduino - 如何使用指针增加(继承的)公共类成员?
【发布时间】:2014-04-26 18:15:31
【问题描述】:

我现在在互联网和论坛上搜索了 3 个小时,但我找不到适合我的正确答案。

过去我只做 C ... 但现在我想用 C++ 做一些 Arduino 的东西(编写一个新的 Lib)。

这里有一个(简化的)我的问题示例:

Class Base
{
public:
    uint8_t buffer[ 20 ];
    uint8_t bufferLength;
protected:
    boolean receiveByte( uint8_t * buf, unint8_t * bufLen );
}

boolean MyClass::receiveByte( uint8_t * buf, unint8_t * bufLen )
{
    if( Serial.available() > 0 )
    {
        buf[ *buflen++ ] = Serial.read();
        return( true );
    }
    return( false );
}

Class MyClass : public Base
{
public:
    void execute( void );
}

void MyClass::execute( void )
{
    if( receiveByte( buffer, &bufferLength ) == true )
    {
        // Do something
    }
}

为什么当我在新继承的类中通过reveiveByte() 方法使用bufferLength 的地址时,bufferLength 没有递增?

【问题讨论】:

  • 我们怎么知道?您没有向我们提供 receiveByte 定义。提供了receive 方法,这就是您要问的吗?你的意思是那些方法是virtual
  • 请注意,这不是使用“长度”参数的正常方式。
  • 如果您收到超过 20 个字节,您将度过糟糕的一天。
  • @CaptainObvlious: Serial.read() 只返回一个字节,代码中没有循环。
  • 当然......在arduino草图中像往常一样有一个循环!^^但它不在我的简化示例中......对不起! ;p

标签: c++ class pointers inheritance arduino


【解决方案1】:

您的代码不起作用,因为 bufferLength 是一个成员变量。指向类成员变量的指针与指向简单变量的指针不同。

在 C++ 中,请记住访问成员变量:

ptrobj->bufferLength = 5;  // via class object instance pointer
aobj.bufferLength = 7;  // via class instance

成员变量的地址不是进入所有内存的地址,它是相对于对象的地址。您来自 C 语言,因此意识到可以将关键字“class”替换为“struct”可能会有所帮助。 class 关键字只有不同的默认访问权限,public、private 等。

在成员函数内部访问变量与外部并没有真正的不同,但编译器隐藏了一个细节。编译器正在添加一个隐式 this 指针

void somememberfunction() {
  bufferLength = 7; // you write this code
  this->bufferLength = 7 // this is really the code
  ...

如果你用 Python 编写,编译器不会插入 self/this 指针,你必须经常输入 self.somevariable。

正如所写,您的问题没有解决方案。您的问题可以表述为“如何在没有对象指针的情况下访问成员变量?”这是基于 C 的函数的常见问题。

您没有在上面声明您的意图。这是我要写的版本

Class Base {
public:
  boolean receiveByte();  // the accessors are public
protected:
  uint8_t buffer[ 20 ];  // the data is encapsulated
  uint8_t bufferLength;
}

boolean MyClass::receiveByte() {
  if( Serial.available() > 0 )  {
    bufferLength++;
    // you would insert protection against overflow here
    buffer[bufferLength] = Serial.read();
    return( true );
  }
  return( false );
}

Class MyClass : public Base {
public:
  void execute( void );
}

void MyClass::execute( void )  {
  if( receiveByte() == true ) {
    // Do something
  }
}

【讨论】:

  • 我明白你的意思。^^ 但是 receifeByte( ) 与两个单独的缓冲区一起使用......一个请求和一个响应缓冲区。但我现在改变了函数:“uint8_t receiveByte(uint8_t * buf, uint8_t bufLen);”。当没有收到任何东西时,它返回 NULL ... 当收到东西时,它返回更新后的长度。 buf 指针正确,因为使用的缓冲区/数组已经是类成员!^^ 但非常感谢您的回答! ;)
猜你喜欢
  • 1970-01-01
  • 2016-06-24
  • 1970-01-01
  • 2013-04-02
  • 2012-04-12
  • 1970-01-01
  • 2015-08-09
相关资源
最近更新 更多