I'm trying to create a way to handle many different versions of a protocol, similar to the question How to handle different protocol versions transparently in c++?. I agree that a chain of inheritance would solve the problem well.
This is how I would do it in Java: create an IParser
interface, and have several ParserV0
, ParserV1
, ... classes, inheriting from each other and implementing IParser
.
I understand that creating that structure is possible in C++ due to some multiple inheritance and virtual
tricks. Here's the catch: in Java, if I wanted a parser, I think, I would be able to say IParser parser = getCorrectVersion(...)
. I would get some version of ParserV0
, etc., implementing IParser
and call the methods I need.
What's the equivalent to that last step in C++? There doesn't seem to be a way for me to ask for any class implementing another and then being able to call its methods.
EDIT:
Here's my attempt at doing what jtedit has suggested, since I have seen similar suggestions around StackOverflow:
class IParser {
public:
virtual const string doSomething(params) = 0;
};
class ParserPreVersion : public IParser {
public:
const string doSomething(params) {
// do some thing
}
};
class ParserFactory {
...
public:
const IParser* generateParser() {
return new ParserPreVersion();
}
};
In another part of my code, I say
const IParser parser = *(ParserFactory().generateParser());
I've been getting compile-time errors with this code and variations of it, though, leading me to ask this question.
In member function 'const IParser* generateParser()':
error: cannot allocate an object of abstract type 'ParserPreVersion'
note: because the following virtual functions are pure within 'ParserPreVersion':
note: virtual const std::string IParser::doSomething(params)
also
error: cannot declare variable 'parser' to be of abstract type 'const IParser'
note: since type 'const IParser' has pure virtual functions
I don't understand exactly why I have the first one, but the second is somewhat expected, and was the main concern in my question.
EDIT 2
And my attempt at what Scis has suggested (code declaring classes and functions is the same)
unique_ptr<IParser> getParser() {
return unique_ptr<IParser>(new ParserV0());
}
auto parser(getParser());
This time, I get a vtable
lookup error, since it seems be looking for the function definition in IParser
.
FINAL EDIT:
I realized my code was a little messy and I was missing some modifiers for parameters, so that the virtual one and the overriding one didn't match up. The errors make a lot of sense. Thank you for your help!
You could use an abstract base class and create the required function as virtual
as noted before the only thing I'd suggest is using unique_ptr
and not raw pointers this way you'll not have to delete
the memory yourself when you are finished using it (similarly to what you'd have in Java):
Here a sample:
unique_ptr<IParse> getParser(int x){
switch (x){
case 1:
return unique_ptr<IParse>(new P1());
break;
case 2:
return unique_ptr<IParse>(new P2());
break;
}
return nullptr;
}
int main() {
auto p1(getParser(1));
p1->foo();
auto p2(getParser(2));
p2->foo();
return 0;
}
where foo
is declared as : virtual void foo() = 0;
. See full example here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With