C++ C++;多态接口

C++ C++;多态接口,c++,inheritance,polymorphism,C++,Inheritance,Polymorphism,我试图创建一种方法来处理协议的许多不同版本,类似于这个问题。我同意一系列的继承将很好地解决这个问题 我在Java中就是这样做的:创建一个IParser接口,并有几个ParserV0,ParserV1。。。类,相互继承并实现IParser 我知道,由于多继承性和虚拟技巧,C++中创建该结构是可能的。strong>这里有一个陷阱:在Java中,如果我想要一个解析器,我想,我可以说IParser parser=getCorrectVersion(…)。我会得到一些版本的ParserV0等,实现IPar

我试图创建一种方法来处理协议的许多不同版本,类似于这个问题。我同意一系列的继承将很好地解决这个问题

我在Java中就是这样做的:创建一个
IParser
接口,并有几个
ParserV0
ParserV1
。。。类,相互继承并实现
IParser

<>我知道,由于多继承性和<代码>虚拟技巧,C++中创建该结构是可能的。strong>这里有一个陷阱:在Java中,如果我想要一个解析器,我想,我可以说
IParser parser=getCorrectVersion(…)
。我会得到一些版本的
ParserV0
等,实现
IParser
,并调用我需要的方法

<>什么是C++中最后一步的等价物?我似乎没有办法要求任何类实现另一个类,然后能够调用它的方法

编辑:

以下是我尝试执行jtedit建议的操作,因为我已经看到了关于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();
    }
};
在我代码的另一部分,我说

const IParser parser = *(ParserFactory().generateParser());
不过,我一直在使用这段代码及其变体时遇到编译时错误,这让我提出了这个问题

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)

我不明白为什么我会有第一个,但第二个在某种程度上是意料之中的,也是我问题的主要关注点

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)
编辑2

以及我对Scis建议的尝试(声明类和函数的代码是相同的)

unique_ptr getParser(){
返回唯一的_ptr(新的ParserV0());
}
自动解析器(getParser());
这次,我得到一个
vtable
查找错误,因为它似乎在
IParser
中查找函数定义

最终编辑:

我意识到我的代码有点凌乱,我缺少一些参数修饰符,因此虚拟的和重写的不匹配。这些错误很有道理。谢谢你的帮助

getCorrectVersion()函数需要返回指向接口(即IParser)的指针

例如:

要能够调用这些方法,您需要的方法必须在IParser中是虚拟的

例如:


您可以使用一个抽象基类并创建所需的函数,如前面所述,作为
virtual
。我唯一建议的是使用
unique\u ptr
而不是原始指针。这样,当您使用完内存后,您就不必
自己删除它(类似于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;
}
unique_ptr getParser(int x){
开关(x){
案例1:
返回唯一的_ptr(新的P1());
打破
案例2:
返回唯一的_ptr(新的P2());
打破
}
返回空ptr;
}
int main(){
自动p1(getParser(1));
p1->foo();
自动p2(getParser(2));
p2->foo();
返回0;
}

其中
foo
声明为:
virtualvoidfoo()=0。请参阅完整示例。

您需要一个抽象工厂或参数化工厂方法;这就是jtedit所描述的。通常在执行此操作时,会使构造函数本身受到保护,并且只公开工厂方法。。更多信息,请查看四人帮创作模式

IParser* getCorrectVersion(int version){

    switch(version){
    case 0: 
         return new ParserV0();
    case 1:
         return new ParserV1();
    }
}
class IParser{
public:
    virtual int getInt() = 0;
};
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;
}