I have two legs up to their knees solidly in the C mud (
) Every time that I try to pull a leg out to place it on the (possibly firmer) C++ mud, the other goes deeper in the C mud and I never get out of it.
I have a scenario where I thought that a base class plus some derived classes would provide a perfect solution. The base class contains a pointer to a c-string.
The first battle was won, the base class requires a default constructor. It seems to be the way C++ works but I really had something like .... I'm now with the one leg one centimeter less deep in the C mud.
The next battle was that I need an array of (different) derived classes; I think that I also won this one by using pointers (I understand why); and again that one leg one centimeter less deep in de C mud.
And another battle that I won was the pure virtual function. Great, the one leg 3 centimeters out of the C mud without sinking the other one deeper into it.
But now I need your help so that I don't sink the legs deeper in the C mud
This is the code that I'm working on to get the understanding and the basics in place.
// base class for upload data
class DsmrData
{
public:
const char *data;
DsmrData(const char *dta)
{
data = dta;
Serial.print(F("UplDta constructor "));
//printData();
}
// we need a default constructor :(
// omitting will result in errors
// why do derived classes call the default constructor; seems to be part of the language :(
DsmrData()
{
Serial.print(F("Default DsmrData constructor "));
//printData();
}
// needs to be a pure virtual function;
virtual void convert() = 0;
void printData()
{
Serial.print(F("'"));
Serial.print(data);
Serial.println(F("'"));
}
};
// derived class for float data to be uploaded
class DsmrFloat : public DsmrData
{
public:
float x;
DsmrFloat(const char *dta)
{
data = dta;
Serial.print(F("DsmrFloat constructor "));
printData();
}
void convert()
{
x = atof(data);
}
};
// derived class for int32_t data to be uploaded
class DsmrInt32 : public DsmrData
{
public:
int32_t x;
DsmrInt32(const char *dta)
{
data = dta;
Serial.print(F("DmsrInt32 constructor "));
printData();
}
void convert()
{
x = atoi(data);
}
};
// derived class for literal data to be uploaded
class DsmrLiteral : public DsmrData
{
public:
char x[51];
DsmrLiteral(const char *dta)
{
data = dta;
Serial.print(F("DsmrLiteral constructor "));
printData();
}
void convert()
{
strcpy(x, data);
}
};
// derived class for text data to be uploaded
class DsmrText : public DsmrData
{
public:
char x[51];
DsmrText(const char *dta)
{
data = dta;
Serial.print(F("DsmrText constructor "));
printData();
}
void convert()
{
strcpy(x, data);
}
};
void setup()
{
Serial.begin(115200);
Serial.println(F("Hi there"));
DsmrInt32 uploadInteger("123");
DsmrFloat uploadFloat("3.14");
DsmrLiteral uploadLiteral("Hello World!");
DsmrData *ui = &uploadInteger;
DsmrData *uf = &uploadFloat;
DsmrData *ut = &uploadLiteral;
DsmrData *dataToUpload2[] = {
&uploadInteger,
uf,
ut,
};
for (uint8_t cnt = 0; cnt < (sizeof(dataToUpload2) / sizeof(dataToUpload2[0])); cnt++)
{
dataToUpload2[cnt]->printData();
dataToUpload2[cnt]->convert();
// error: 'DsmrData' has no member named 'x'
Serial.println(dataToUpload2[cnt]->x);
}
}
void loop() {
// put your main code here, to run repeatedly:
}
The error
DSMRwithClasses:138:40: error: 'class DsmrData' has no member named 'x'
Serial.println(dataToUpload2[cnt]->x);
- Obviously it does not have a member variable x, in my view that is the whole purpose of the use of derived classes.
- I can obviously use some form of a cast but that would imply that either the code needs to know the type or I must cast manually (no idea how); it also defeats, in my view, the purpose of the derived classes, it should be 'automagic'.
Please advise what I'm missing and how I could solve this; I've googled this on-and-off for a a couple of days now and haven't been able to solve it ![]()
Thanks in advance to those that can help me not to get more firmly in the C mud ![]()