我试图了解一些用于ESP32 EPaper模块(TTGO T5 V2.2)的代码。当按下三个按钮之一时,该程序利用Button2库处理事件。它为每个按钮初始化一个对象,并将其存储在指针数组中。当我要编译代码时,出现以下错误:
error: no matching function for call to 'Button2::Button2()'
(信息:Button2 * pBtns = nullptr; args = 3;) 发生错误的代码行是:
pBtns = new Button2 [args];
到目前为止,我知道,这行是否应该在堆上为该新对象保留内存。那么为什么要有一个功能,它的目的是什么?
到目前为止,我尝试使用固定的数组大小,并使用互联网上某个地方的一些示例中的片段:
//Button2 pBtns[5] = {nullptr,nullptr,nullptr,nullptr,nullptr};
//Button2 pBtns[5];
//Button2* pBtns = static_cast<Button2*>( ::operator new ( sizeof(Button2) * (sizeof(g_btns) / sizeof(g_btns[0]))));
// g_btns[] is the array of gpio pins of the buttons
由于缺少示例,我仍然不知道是否丢失了某些内容,但是如果我没记错的话,“没有匹配的调用函数”错误提示对象本身存在问题... < / p>
// in Button2.h:
class Button2 {
private:
.// some private defs ...
public:
Button2(byte attachTo, byte buttonMode = INPUT_PULLUP, unsigned int debounceTimeout = DEBOUNCE_MS);
.// some methods here ...
bool operator==(Button2 &rhs);
void loop();
};
// in program code:
#define BUTTONS_MAP {37,38,39}
Button2 *pBtns = nullptr;
uint8_t g_btns[] = BUTTONS_MAP;
void button_init()
{
uint8_t args = sizeof(g_btns) / sizeof(g_btns[0]);
pBtns = new Button2 [args]; //<<<<<<< COMPILER-ERROR is HERE
//pBtns = new Button2;
for (int i = 0; i < args; ++i) {
pBtns[i] = Button2(g_btns[i]);
pBtns[i].setPressedHandler(button_callback);
}
}
在上面的示例中,我希望pBtns包含一个具有3个指向新创建和初始化对象的指针的数组。另外,我想知道错误消息中的功能是什么。当我理解原理并付诸实践时,我喜欢将对象存储在数组中的想法,并希望在我自己的开发中使用它-那么技术的优缺点是什么?
(长文本为sri-只是不知道有什么用,所以请捉住我的大脑!)
答案 0 :(得分:3)
分配数组时,程序将尝试默认构造元素。
您无法使用默认构造Button2
,因为定义其他构造函数会禁用自动生成的默认构造函数。您需要添加默认构造函数或移至a smarter container like std::vector
。
示例:
Button2 *pBtns = nullptr;
成为
std::vector<Button2> btns;
然后使用
在vector
中创建按钮
btns.emplace_back(<arguments>);
作为额外的奖励,vector
消除了动态分配的阵列使您难以承受的所有内存管理工作。
答案 1 :(得分:1)
问题是缺少由运算符new []
调用的默认(无参数)构造函数。
要定义一个,请将此行添加到class Button2
定义中:
Button2() = default; // after C++11
或
Button2() {} // before C++11
假设您的所有成员也都具有默认构造函数(最有可能),则应该使用JustWork( TM )
答案 2 :(得分:0)
Button2 *pBtns
不是指针数组,而是指向一个或多个实际Button2
对象的指针。这就是new[]
试图构造此类对象的原因。
您需要
Button2 **pBtns=nullptr;
...
pBtns=new *Button2[args];
然后可以使用pBtns[i]=new Button2(...);
进行循环。
但这是C式的(减去new
的使用),现代C ++代码更可能使用std::vector
,如注释和其他答案所建议的。