Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何正确初始化C++;Arduino程序中的对象?_C++_Oop_Pointers_Arduino - Fatal编程技术网

C++ 如何正确初始化C++;Arduino程序中的对象?

C++ 如何正确初始化C++;Arduino程序中的对象?,c++,oop,pointers,arduino,C++,Oop,Pointers,Arduino,在我的简单的Arduino项目中,为了保持整洁,我决定创建一个“模式管理器”,处理一种模式和另一种模式之间的传递。基本概念是,每次我想要更改模式时,它都会实例化下一个模式并替换上一个模式 请注意,我有12年以上的OOP和java/Scala经验,但在C++中没有任何经验,只是需要一个ARDUNO做的东西,没有太多的结构。 通过一些研究,我成功地创建了以下“接口”结构: 文件:modes/ModeManager.h。这应该保留对当前模式的引用,并将循环和实例化下一个模式委托给它(每个模式将知道哪一

在我的简单的Arduino项目中,为了保持整洁,我决定创建一个“模式管理器”,处理一种模式和另一种模式之间的传递。基本概念是,每次我想要更改模式时,它都会实例化下一个模式并替换上一个模式

请注意,我有12年以上的OOP和java/Scala经验,但在C++中没有任何经验,只是需要一个ARDUNO做的东西,没有太多的结构。 通过一些研究,我成功地创建了以下“接口”结构:

文件:
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,但似乎有一个智能指针可用: 我推荐