Polymorphic C ++ Interfaces

I am trying to create a way to handle many different versions of a protocol, similar to the question How to handle different versions of a protocol transparently in C ++? . I agree that the inheritance chain will solve the problem.

Here's how I would do it in Java: create an interface IParserand have several classes ParserV0, ParserV1... that inherit from each other and implement IParser.

I understand that creating this structure is possible in C ++ due to some multiple inheritance and tricks virtual. Here's the catch : in Java, if I wanted the parser, I think I can tell IParser parser = getCorrectVersion(...). I would get some version ParserV0, etc., Implementing IParserand calling the methods that I need.

What is equivalent to this last step in C ++? It seems that I have no way to ask for some class that implements another, and then the ability to call its methods.

EDIT:

Here's my attempt to do what jtedit suggested, since I saw 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 get errors during compilation with this code and its variations, which prompts 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)

and

error: cannot declare variable 'parser' to be of abstract type 'const IParser'
note:   since type 'const IParser' has pure virtual functions

I do not quite understand why I have the first, but the second is somewhat expected and was the main problem in my question.

EDIT 2

And my attempt to suggest Scis (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 search error vtablebecause it looks like it is looking for a function definition in IParser.

COMPLETION:

, , , . . !

+4
3

virtual, , , unique_ptr, , delete , ( , Java):

:

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;
}

foo : virtual void foo() = 0;. . .

+3

getCorrectVersion() , IParser

:

IParser* getCorrectVersion(int version){

    switch(version){
    case 0: 
         return new ParserV0();
    case 1:
         return new ParserV1();
    }
}

, IParser

:

class IParser{
public:
    virtual int getInt() = 0;
};
+3

You need an abstract Factory or parameterized Factory method; which is sorted by jtedit description. Usually, you protect the constructor yourself and set only the Factory method. Learn more about the gang of four creation patterns.

http://en.wikipedia.org/wiki/Design_Patterns

+1
source

Source: https://habr.com/ru/post/1544231/


All Articles