问题描述
正在为向 ESP8266 设备发送信息的特定硬件实现串行接收库,我遇到了以下问题
一些背景:
- 我使用 sloeber eclipse IDE 进行 arduino 编程,使用 Arduino IDE 也存在同样的问题
- __cplusplus 给了我 201103,所以我假设我使用的是 c++11
设置说明:
- 我有派生类代表从串行接收的解释包
- 这些类都是基类的派生形式,基类实现了一些常用方法,这里是methodA(实际上:长度为 数据,以及数据的吸气剂)
- 为了转发这些数据包,我创建了一个类,其中包含一个结构体 (sData) 的成员,该结构体内部有一个标记联合。为简单起见,我在这里只使用 sData 而不是包含它的类。
- union uUnion 是以派生包的形式保存数据包内容的联合,一次只有一个,但能够包含每个可用的派生类。
- 我不使用任何动态对象创建(没有新的),以防止内存泄漏
也许这个问题有更好的解决方案。想法表示赞赏。但我想重点讨论为什么我的实现不起作用
问题
联合外派生类的成员函数的使用。 我可以毫无问题地直接打电话给他们。 但是我无法从联合中创建指向派生类实例的指针并调用该成员。
//this is the base class
class cBaseA{
public:
virtual void methodA(void){
Serial.print(" A ");
Serial.println(i);
}
int i; //some attribute to work with
private:
};
//first derived class
class cDerivedA: public cBaseA{
public:
void methodA(void) {
Serial.print(" DerivedA ");
Serial.print(i);
Serial.print(" ");
Serial.println(ii);
}
int ii; //additional attribute
private:
};
//second derived class
class cDerivedB: public cBaseA{
public:
void methodA(void) {
Serial.print(" DerivedB ");
Serial.print(i);
Serial.print(" ");
Serial.println(ii);
}
int ii;
private:
};
//third derived class
class cDerivedC: public cBaseA{
public:
void methodA(void) {
Serial.print(" DerivedC");
Serial.print(i);
Serial.print(" ");
Serial.println(ii);
}
int ii;
private:
};
//this is the structure to pass different derived instances around
struct sData{
enum eDataType{
eunkown,eDerivedA,eDerivedB,eDerivedC
} DataType;
union uUnion{
cDerivedA DerivedA;
cDerivedB DerivedB;
cDerivedC DerivedC;
~uUnion(){};
uUnion(){};
} ;
uUnion DataUnion;
sData(void){DataType=eDataType::eunkown;};
sData(const sData &Data){
this->DataType=Data.DataType;
switch(this->DataType){
case eDataType::eDerivedA:
this->DataUnion.DerivedA=Data.DataUnion.DerivedA;break;
case eDataType::eDerivedB:
this->DataUnion.DerivedB=Data.DataUnion.DerivedB;break;
case eDataType::eDerivedC:
this->DataUnion.DerivedC=Data.DataUnion.DerivedC;break;
case eDataType::eunkown:
break;
}
}
~sData(){};
};
void DataFunction(struct sData *Data){
Serial.println("A1:");
Data->DataUnion.DerivedB.methodA(); //works fine
cDerivedB *DerivedB;
DerivedB=&(Data->DataUnion.DerivedB); //this works
DerivedB->methodA(); //compiles,but execution exception,code 28
}
void setup(){
Serial.begin(9600);
delay(2000);
sData Data;
cDerivedB DerivedB1;
DerivedB1.i=1;
DerivedB1.ii=2;
Data.DataType=sData::eDataType::eDerivedB;
Data.DataUnion.DerivedB=DerivedB1;
DataFunction(&Data);
}
到目前为止我尝试过的:
-
没有
cBaseA
的虚拟析构函数没有影响(我已经尝试过) -
使工会匿名并没有改变任何东西
-
cDerivedB &DerivedB; DerivedB=&(Data->DataUnion.DerivedB); DerivedB.methodA();
-
我能够复制到基类的联合之外,但这会导致切片,并且调用在基类中结束,而不是我在派生类中需要的
问题是:如果可以直接调用,为什么会出现这个异常?
获取联合内容的句柄(指针、引用)并调用成员的正确方法是什么?我知道那里有讨论,联合应该只包含简单的数据类型。这只是编译器(c + 11)让我写这个的缺陷吗? 但是,直接访问仍然是可能的。为什么不通过指针?
如果有人能够把那朵云移开,我看不透,非常感谢。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)