C++ 如何正确初始化C++;Arduino程序中的对象?
在我的简单的Arduino项目中,为了保持整洁,我决定创建一个“模式管理器”,处理一种模式和另一种模式之间的传递。基本概念是,每次我想要更改模式时,它都会实例化下一个模式并替换上一个模式 请注意,我有12年以上的OOP和java/Scala经验,但在C++中没有任何经验,只是需要一个ARDUNO做的东西,没有太多的结构。 通过一些研究,我成功地创建了以下“接口”结构: 文件:C++ 如何正确初始化C++;Arduino程序中的对象?,c++,oop,pointers,arduino,C++,Oop,Pointers,Arduino,在我的简单的Arduino项目中,为了保持整洁,我决定创建一个“模式管理器”,处理一种模式和另一种模式之间的传递。基本概念是,每次我想要更改模式时,它都会实例化下一个模式并替换上一个模式 请注意,我有12年以上的OOP和java/Scala经验,但在C++中没有任何经验,只是需要一个ARDUNO做的东西,没有太多的结构。 通过一些研究,我成功地创建了以下“接口”结构: 文件:modes/ModeManager.h。这应该保留对当前模式的引用,并将循环和实例化下一个模式委托给它(每个模式将知道哪一
modes/ModeManager.h
。这应该保留对当前模式的引用,并将循环和实例化下一个模式委托给它(每个模式将知道哪一个是下一个)
\ifndef\uu模式\u管理器__
#定义模式管理器__
#包括
#包括“模式/模式h”
类模式管理器{
私人:
模式*模式;
公众:
ModeManager();
~ModeManager(){};
虚空回路(uint8_t电压);
};
#恩迪夫
文件:modes/Mode.h
是运行程序实循环函数的实际“模式”。它还处理下一个模式的实例化
\ifndef\uu模式__
#定义模式__
#包括
类模式{
公众:
模式(){}
虚拟~Mode(){}
虚空回路(uint8_t电压)=0;
虚空getNext(模式*目标)=0;
};
#恩迪夫
文件:modes/ModeManager.cpp
#包括“ModeManager.h”
#包括
#包括
#包括“模式/模式h”
#包括“模式/DummyMode.h”
#定义电压\u下一个\u模式5
ModeManager::ModeManager(){
DummyMode cmode=DummyMode();
mode=&cmode;//我不确定该怎么做
}
无效模式管理器::环路(uint8\u t电压){
如果(电压==电压\u下一个\u模式){
Serial.println(“切换到下一个模式”);
模式->获取下一步(模式);
}否则{
Serial.println(“调用模式循环”);
模式->回路(电压);//从这里开始,什么都没有。
}
}
文件:modes/DummyMode.h
\ifndef\uu虚拟模式__
#定义虚拟模式__
#包括“模式/模式h”
类DummyMode:公共模式{
公众:
DummyMode();
~DummyMode(){}
虚空回路(uint8_t电压);
虚拟void getNext(模式*目标);
};
#恩迪夫
文件:modes/DummyMode.cpp
#包括“modes/DummyMode.h”
#包括
DummyMode::DummyMode(){
Serial.println(“虚拟模式初始化”);
}
无效DummyMode::回路(uint8\u t电压){
串行打印(“电压:”);
串行打印LN(电压);
}
void DummyMode::getNext(模式*目标){
DummyMode nextMode=DummyMode();
目标=&nextMode;
}
最后是我的main.cpp
#包括
#包括“modes/ModeManager.h”
#包括“modules/memory.h”
#包括“模块/监视器.h”
ModeManager*ModeManager;
无效设置(){
引脚模式(A0,输入);
Serial.begin(9600);
Serial.println(“Init”);
ModeManager mm=ModeManager();
modeManager=&mm;
}
无效循环(无效){
uint8_t电压=map(模拟读数(A0),0,1024,0,5);
modeManager->loop(电压);
}
现在,理论上我看不出有什么理由不起作用。实际上,我99.9%肯定我在初始化和指针方面做错了什么。
当我尝试运行此代码时,我会输出以下序列号:
Init
Initialization of dummy mode
Calling mode loop
这意味着它在循环的第一次迭代时冻结,就在调用mode->loop(电压)之前代码>
谁能给我指出正确的方向吗?再次,我真的没有经验的C++,我知道如何使这个结构来自各种在线资源的C++编程,包括一些答案在这里,所以请容忍我 < p>这里:< /p>
DummyMode cmode = DummyMode();
您正在创建一个具有自动生存期(通常称为堆栈上的)的DummyMode
实例cmode
然后获取地址并将其分配给另一个变量:
mode = & cmode; // I'm not sure how this should actually be done
由于cmode
是具有自动生存期的对象,因此当程序离开创建它的作用域时,它将被销毁。因此,存储在模式下的指针将悬空并指向不再存在的对象。取消对它的引用将触发未定义的行为
看起来您的意图是创建具有动态生存期的对象。
您可以通过以下方法实现此目的:
mode = new DummyMode();
尽管如此,您仍有责任确保在不再需要该对象时将其销毁。
这将通过删除完成:
delete mode;
<> >在更为习惯/现代的C++中,通常使用智能指针来管理此类对象的生命周期,而不是手动调用<代码>删除< /代码>。我看到C++的标准库不适用于Arduino,但似乎有一个智能指针可用:
我建议您仔细研究一下如何使用它,以更轻松地避免内存泄漏。这里:
DummyMode cmode = DummyMode();
您正在创建一个具有自动生存期(通常称为堆栈上的)的DummyMode
实例cmode
然后获取地址并将其分配给另一个变量:
mode = & cmode; // I'm not sure how this should actually be done
由于cmode
是具有自动生存期的对象,因此当程序离开创建它的作用域时,它将被销毁。因此,存储在模式下的指针将悬空并指向不再存在的对象。取消对它的引用将触发未定义的行为
看起来您的意图是创建具有动态生存期的对象。
您可以通过以下方法实现此目的:
mode = new DummyMode();
尽管如此,您仍有责任确保在不再需要该对象时将其销毁。
这将通过删除完成:
delete mode;
<> >在更为习惯/现代的C++中,通常使用智能指针来管理此类对象的生命周期,而不是手动调用<代码>删除< /代码>。我看到C++的标准库不适用于Arduino,但似乎有一个智能指针可用:
我推荐