lass ThingABC {
public:
virtualvoid Serialise(ostream& out) = 0;
virtualvoid Deserialise(istream& in) = 0;
};
class MyThing : public ThingABC{
private:
int someOtherMember = 0;
public:
MyThing(int num) : someOtherMember(num) {}
void Serialise(ostream& out) {
out << someOtherMember;
}
void Deserialise(istream& in) {
in >> someOtherMember;
}
int getSOM() {
return someOtherMember;
}
};
class ThingHolder {
private:
ThingABC* thing; // a pointer as ThingABC cannot be directly instantiated
string nm = "thing";
public:
ThingHolder(ThingABC* newThing) : thing (newThing) {}
ThingABC* getThing() const {
return thing;
}
};
int main()
{
ThingHolder thingholder(new MyThing(4322));
std::cout << thingholder.getThing() -> getSOM();
}
This produces the following error:
main.cpp: In function ‘int main()’:
main.cpp:57:44: error: ‘class ThingABC’ has no member named ‘getSOM’
std::cout << thingholder.getThing() -> getSOM();
^~~~~~
ThingABC has no member named getSOM() but its subclass MyThing does. Do I need to cast ThingABC* to MyThing*? If so, how do I do this?
If you want to use polymorphism, you would have getSOM() be a virtual function in the base-class and override it in the MyThing class.
Then, you can call the function through a base-class pointer or reference, and have it perform sub-class behavior.
If you are going to have other sub-class with different variables, you should perhaps rename your getX function to something less specific. The issue is your example is very abstract (what exactly is a "ThingHolder"? What is the purpose of this design?), so it's hard to see the kind of design this is supposed to become. You can use casting as a workaround, but if you're not careful you can break things. static_cast<MyThing*>(thingholder.getThing())
PS: When making minimal examples like you did above, please also add the stuff at the top like #includes, usings, etc. so that people on the forum can click to run your code without having to manually edit it.