【问题标题】:Arduino Error (C++) : invalid use of non-static data memberArduino错误(C++):非静态数据成员的无效使用
【发布时间】:2016-07-10 07:09:09
【问题描述】:

我正在制作一个可扩展的 Arduino 库,但我收到编译器错误:invalid use of non-static data member

我的代码: LedCube.h:

#ifndef LedCube_h
#define LedCube_h
#include "Arduino.h"
class LedCube {
  private:
  int _x, _y, _z;
  byte _lPins[_y];
  byte _cPins[_z][_x];
  public:
  LedCube(int x, int y, int z, byte *lPins, byte (*cPins)[_x]);
  void displayFrame(bool frame[][_x][_z]);
  void displayLayer(int i, bool frame[][_x][_z]);
};
#endif

Ledcube.ino(cpp):

#include "Arduino.h"
#include "LedCube.h"

int _x, _y, _z;
//bool frame[y][z][x] = {0};
byte _lPins[_y];
byte _cPins[_z][_x];

LedCube::LedCube(int x, int y, int z, byte lPins[], byte cPins[][_x]) {
  _x = x;
  _y = y;
  _z = z;
  _lPins = lPins;
  _cPins = cPins;
}

void LedCube::displayFrame(bool frame[_y][_x][_z]) {
  int i;
  for(i=0;i<_y;i++) {
    displayLayer(i, frame);
    pinMode(_lPins[i], OUTPUT);
    delay(1);
    pinMode(_lPins[i], INPUT);
  }
}

void LedCube::displayLayer(int i, bool frame[_y][_x][_z]) {
  int j,k;
  for(j=0;j<_z;j++) {
    for(k=0;k<_x;k++) {
      if(frame[i][j][k]) {
        digitalWrite(_cPins[j][k], HIGH);
      }
      else {
        digitalWrite(_cPins[j][k], LOW);
      }
    }
  }
}

我想在构造函数中接受变量xyz并将它们设置为_x_y_z,因此不想设置变量@987654330 @。 我正在使用这些变量来声明一个循环。

我得到的错误是:

Arduino: 1.6.5 (Windows 10), Board: "Arduino/Genuino Mega or Mega 2560, ATmega2560 (Mega 2560)"

In file included from LedCube.ino:2:0:
LedCube.h:12: error: invalid use of non-static data member 'LedCube::_y'
   int _x, _y, _z;
           ^
LedCube.h:13: error: from this location
   byte _lPins[_y];
               ^
LedCube.h:12: error: invalid use of non-static data member 'LedCube::_z'
   int _x, _y, _z;
               ^
LedCube.h:14: error: from this location
   byte _cPins[_z][_x];
               ^
LedCube.h:12: error: invalid use of non-static data member 'LedCube::_x'
   int _x, _y, _z;
       ^
LedCube.h:14: error: from this location
   byte _cPins[_z][_x];
                   ^
LedCube.h:12: error: invalid use of non-static data member 'LedCube::_x'
   int _x, _y, _z;
       ^
LedCube.h:16: error: from this location
   LedCube(int x, int y, int z, byte *lPins, byte (*cPins)[_x]);
                                                           ^
LedCube.h:12: error: invalid use of non-static data member 'LedCube::_x'
   int _x, _y, _z;
       ^
LedCube.h:17: error: from this location
   void displayFrame(bool frame[][_x][_z]);
                                  ^
LedCube.h:12: error: invalid use of non-static data member 'LedCube::_z'
   int _x, _y, _z;
               ^
LedCube.h:17: error: from this location
   void displayFrame(bool frame[][_x][_z]);
                                      ^
LedCube.h:12: error: invalid use of non-static data member 'LedCube::_x'
   int _x, _y, _z;
       ^
LedCube.h:18: error: from this location
   void displayLayer(int i, bool frame[][_x][_z]);
                                         ^
LedCube.h:12: error: invalid use of non-static data member 'LedCube::_z'
   int _x, _y, _z;
               ^
LedCube.h:18: error: from this location
   void displayLayer(int i, bool frame[][_x][_z]);
                                             ^
LedCube:6: error: array bound is not an integer constant before ']' token
LedCube:7: error: array bound is not an integer constant before ']' token
LedCube:7: error: array bound is not an integer constant before ']' token
In file included from LedCube.ino:2:0:
LedCube.h:12: error: invalid use of non-static data member 'LedCube::_x'
   int _x, _y, _z;
       ^
LedCube:9: error: from this location
LedCube.ino: In constructor 'LedCube::LedCube(...)':
LedCube:10: error: 'x' was not declared in this scope
LedCube:11: error: 'y' was not declared in this scope
LedCube:12: error: 'z' was not declared in this scope
LedCube:13: error: '_lPins' was not declared in this scope
LedCube:13: error: 'lPins' was not declared in this scope
LedCube:14: error: '_cPins' was not declared in this scope
LedCube:14: error: 'cPins' was not declared in this scope
In file included from LedCube.ino:2:0:
LedCube.h: At global scope:
LedCube.h:12: error: invalid use of non-static data member 'LedCube::_y'
   int _x, _y, _z;
           ^
LedCube:17: error: from this location
In file included from LedCube.ino:2:0:
LedCube.h:12: error: invalid use of non-static data member 'LedCube::_x'
   int _x, _y, _z;
       ^
LedCube:17: error: from this location
In file included from LedCube.ino:2:0:
LedCube.h:12: error: invalid use of non-static data member 'LedCube::_z'
   int _x, _y, _z;
               ^
LedCube:17: error: from this location
LedCube.ino: In member function 'void LedCube::displayFrame(...)':
LedCube:20: error: 'frame' was not declared in this scope
LedCube:21: error: '_lPins' was not declared in this scope
In file included from LedCube.ino:2:0:
LedCube.h: At global scope:
LedCube.h:12: error: invalid use of non-static data member 'LedCube::_y'
   int _x, _y, _z;
           ^
LedCube:27: error: from this location
In file included from LedCube.ino:2:0:
LedCube.h:12: error: invalid use of non-static data member 'LedCube::_x'
   int _x, _y, _z;
       ^
LedCube:27: error: from this location
In file included from LedCube.ino:2:0:
LedCube.h:12: error: invalid use of non-static data member 'LedCube::_z'
   int _x, _y, _z;
               ^
LedCube:27: error: from this location
LedCube.ino: In member function 'void LedCube::displayLayer(...)':
LedCube:31: error: 'frame' was not declared in this scope
LedCube:31: error: 'i' was not declared in this scope
LedCube:32: error: '_cPins' was not declared in this scope
LedCube:35: error: '_cPins' was not declared in this scope
invalid use of non-static data member 'LedCube::_y'

  This report would have more information with
  "Show verbose output during compilation"
  enabled in File > Preferences.

我只想定位这个错误,而不是输出中的其他错误。

【问题讨论】:

  • 你不能做byte _lPins[_y];。但是您可以使用 std::vector&lt;byte&gt; 并在构造函数初始化列表中设置其长度。问题:Arduino 编译器不一定支持 C++ 标准库,如std::vector。解决方法:网上找这样的实现。
  • 为什么有一个类成员_lPins,还有一个全局变量_lPins

标签: c++ arrays compiler-errors arduino


【解决方案1】:
class LedCube {
  private:
  int _x, _y, _z;
  byte _lPins[_y];
  byte _cPins[_z][_x];

上面的代码没有任何意义,Arduino 与否。 (记住 Arduino 使用 C++)。

您正在尝试定义长度为 _x, _y, _z 的数组 _lPins_cPins 未初始化。一个类必须有一个固定的大小,这样当你实例化它时,编译器就知道要分配多少内存(在调用构造函数之前)。它如何为未知大小的数组分配内存?


(已编辑添加)

我认为 StackOverflow 有建设性的回答政策。如果您认为我做错了什么,请给出解决方案(这就是我在这里的原因)。

我很想知道您为什么接受“您的代码:... 错误”的答案。但对我的冒犯。接受的答案没有发布解决方案代码,只是一些指导方针。

你的这段代码,不在类定义中,也犯了同样的错误:

int _x, _y, _z;
//bool frame[y][z][x] = {0};
byte _lPins[_y];
byte _cPins[_z][_x];

这也会产生错误。您不能声明这样的静态数组,其边界为x, _y, _z,其中x, _y, _z 不是常量。当您更改 x, _y, _z 时,该数组将不会重新定义其长度。


在您的构造函数中,您将作为参数传递一个名称 _x,它也是一个类变量。

LedCube::LedCube(int x, int y, int z, byte lPins[], byte cPins[][_x]) {

C++ 不允许你像这样分配数组:

 _lPins = lPins;
 _cPins = cPins;

你有很多错误,而不仅仅是一个,例如。

LedCube:20: error: 'frame' was not declared in this scope
LedCube:21: error: '_lPins' was not declared in this scope

你真的应该把它们都清理干净。


同样,您的平台上也不提供 IIRC、new 和 delete

实际上Arduino提供了newdelete,以及mallocfree


我正在尝试具有建设性,但没有单行解决方案。需要返工,很抱歉告诉你。你可能想做一些 C++ 教程。您正在编写的代码(尽管我可以看到您正在尝试做什么)是您希望该语言以某种方式工作,而事实并非如此。


可能的实现

以下是根据提供的数组大小在构造函数中分配引脚结构的一种可能方法。我不认为这是一个很好的实现,但至少它有效。 showPins 函数显示数据已正确保留。

class LedCube {
  private:
    const int x_, y_, z_;
    byte * lPins_;
    byte * cPins_;
  public:
    LedCube(const int x, const int y, const int z, byte *lPins, byte *cPins);  // constructor

    void showPins () const;
};

byte lPins [3] = { 5, 6, 7 };
byte cPins [2] [4] = {
    { 1, 2, 3, 4 },    // 0
    { 8, 9, 10, 11 },  // 1
};

LedCube::LedCube (const int x, const int y, const int z, byte *lPins, byte *cPins)
    : x_ (x), y_ (y), z_ (z)
  {
  lPins_ = new byte [y];
  cPins_ = new byte [x * z];
  if (lPins_ == NULL || cPins_ == NULL)
    exit (1);
  memcpy (lPins_, lPins, sizeof (byte) * y);
  memcpy (cPins_, cPins, sizeof (byte) * x * z);
  }

void LedCube::showPins () const
  {
  Serial.println (F("lPins:"));
  for (int i = 0; i < y_; i++)
    Serial.println (lPins_ [i]);
  Serial.println (F("cPins:"));
  for (int j = 0; j < x_; j++)
    {
    Serial.print (F("z = "));
    Serial.println (j);
    for (int k = 0; k < z_; k++)
      Serial.println (cPins_ [j * z_ + k]);
    } 
  }

LedCube foo (2, 3, 4, (byte *) lPins, (byte *) cPins);

void setup() 
{
  Serial.begin (115200);
  Serial.println ();
  foo.showPins ();
}

void loop() 
{

}

输出:

lPins:
5
6
7
cPins:
z = 0
1
2
3
4
z = 1
8
9
10
11

【讨论】:

  • 我正在编写一个库,引用的代码来自仅包含声明的头文件。变量正在由构造函数在 .ino 文件中初始化。
  • 我认为 StackOverflow 有建设性的回答政策。如果您认为我做错了什么,请给出解决方案(这就是我在这里的原因)。
  • “给出解决方案”不仅仅是在这种特殊情况下更正一行代码。它基本上是一个重写。请参阅我修改后的答案。
  • @Nick_Gammon 很抱歉造成误解。实际上,这是我在 2012 年之后第一次尝试编写复杂的 C++ 代码,也是在一个新平台上。通过“给出解决方案”,我的意思是阅读材料或指导方针之类的东西,可以为我指明正确的方向。我接受了对方的答案,因为他/她的答案是当时唯一可用的答案(其他人:请不要介意)。另外我只想要不同对象中不同但长度不变的数组。对不起,谢谢。
  • @sbrm1 首先,我不介意!但是,您也可以考虑将数组大小设为非类型模板参数。但值得注意的是,如果您需要大量不同大小的立方体,您可能会遇到代码大小问题,具体取决于存在的模板实例的数量和编译器优化器的聪明程度。我认为这是值得考虑的,因为生成的代码会更简单——如果可能,应该避免动态分配。
【解决方案2】:

您的代码:byte _lPins[_y]; byte _cPins[_z][_x]; 错误。 C++ 不支持变长数组,这意味着_y_x_z 必须是常量表达式。

请记住,对象的大小在编译时必须保持不变,这样您就不会再犯该错误了。

解决此问题的“正确”方法是使用std::vector,但我相信它在您的平台上不存在,但您应该检查一下。 IIRC,唯一可用的库是来自 avr-libc 的标准 C 的子集。

您必须自己根据需要动态分配内存。同样,您的平台上也没有提供 IIRC、newdelete(但同样,您必须检查我),所以您必须使用 mallocfree 并做事旧的 C 方式。有大量资源可用于如何在线执行此操作。

【讨论】:

  • 请注意,我使用的是 Arduino IDE,它基本上实现了 Wiring 语言规范。
  • avr-gcc 和 avr-libc 没有使用,规格可能不同。
  • 即使 C++ 确实支持 VLA,您仍然无法在结构中使用它们。由于显而易见的原因,必须在编译时知道结构的大小。
  • @sbrm1 根据this,后端使用了avr-gcc。
  • @Max_Bozzi 好的,但它与 AVR Studio 中使用的规范不同,我假设您正在谈论它。 Arduino 支持newdelete。 @M.M 我不想要 VLA,只想要类的不同对象中不同大小的数组,这在它们各自的实例中是不变的。
猜你喜欢
  • 1970-01-01
  • 2015-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-12
  • 2023-03-12
  • 2013-10-14
  • 2019-05-13
相关资源
最近更新 更多