我正在编写ESP32 UI,并且遇到了这个问题:
我有一个Menu类,并在其标题中定义了一个向量_menuItemStack。
我从外部创建一个对象MenuItem并将其传递给函数addMenuItem(MenuItem menuItem)。它将其添加到堆栈中。当我在Menu.cpp中声明矢量时,它会运行。但这不是每个对象都唯一,我认为它是静态的吗?
因此,我将在标头中将向量声明为私有,同时它将进行编译。它立即崩溃。
我的错误是什么? C ++伤了我的头。
Menu.h
/*
Menu.h - Menu Class
*/
#ifndef Menu_h
#define Menu_h
#include "Arduino.h"
#include "StackArray.h"
#include "MenuItem.h"
#include "SPI.h"
#include "U8g2lib.h"
class Menu
{
public:
Menu();
void update();
void draw();
void addMenuItem(MenuItem menuItem);
private:
int arrayPos;
std::vector<MenuItem> _menuItemStack;
};
#endif
Menu.cpp
#include "Menu.h"
extern U8G2_SSD1327_MIDAS_128X128_2_4W_HW_SPI u8g2;
Menu::Menu() {
arrayPos = 0;
}
void Menu::draw() {
u8g2.setFont(u8g2_font_6x10_tf);
int posY = 0;
for (MenuItem &m : _menuItemStack){
u8g2.drawStr(0,posY+15,m.getText().c_str());
posY+=15;
}
}
void Menu::update() {
}
void Menu::addMenuItem(MenuItem menuItem){
arrayPos++;
_menuItemStack.push_back(menuItem);
//debug
Serial.println(arrayPos);
Serial.println(menuItem.getText());
}
注意:std :: stdlib在更高的位置。
编辑:
MenuItem.cpp
#include "MenuItem.h"
extern U8G2_SSD1327_MIDAS_128X128_2_4W_HW_SPI u8g2;
MenuItem::MenuItem() {
_text = new String;
}
MenuItem::MenuItem(const MenuItem &obj){
_text = new String;
*_text = *obj._text;
}
void MenuItem::draw(){
}
void MenuItem::update(){
}
void MenuItem::setText(String txt){
*_text = txt;
}
String MenuItem::getText(){
return *_text;
}
void MenuItem::attachHandler(CallbackFunction f){
callback = f;
}
void MenuItem::run(){
if (callback != NULL) callback();
}
MenuItem.h
#ifndef MenuItem_h
#define MenuItem_h
#include "Arduino.h"
#include "StackArray.h"
#include "SPI.h"
#include "U8g2lib.h"
class MenuItem
{
private:
typedef void (*CallbackFunction)();
CallbackFunction callback = NULL;
String *_text;
public:
MenuItem();
MenuItem(const MenuItem &obj);
void draw();
void update();
void run();
void setText(String txt);
void attachHandler(CallbackFunction f);
String getText();
};
#endif
答案 0 :(得分:0)
调用std::vector::push_back
时,将创建对象的副本并将其存储到向量中。因此,请首先检查您的类的副本构造函数,以及是否可能由该错误引起。
然后,您需要知道std::vector
所需的存储器存储在哪里。
在嵌入式目标上,您可能未使用传统的标准库,并且操纵内存可能很棘手。
当将向量声明为全局变量时,与将其声明为类的私有成员时相比,所需的内存很有可能不在同一区域中。这将取决于您的平台,编译器,链接器脚本以及您使用的lib C ++。 std::vector
使用分配器,在Linux上您可以不用看它做什么,而在嵌入式目标上时,您需要知道您正在使用哪个分配器以及内存在哪里。
您可以尝试打印std::vector::data()
的地址进行检查。然后,您可能必须提供自己的分配器,或保留足够大的内存部分来容纳向量,并在此内存地址处初始化向量中包含的数据。
答案 1 :(得分:0)
传递给menuItem
函数的addMenuItem
是一个具有寿命的副本,直到该函数结束为止。
请尝试传递菜单项作为参考,以便将使用寿命比addMenuItem
函数长的对象填充菜单项列表。这样将签名更改为:
void Menu::addMenuItem(MenuItem& menuItem)