我正在尝试创建一种方法来处理协议(protocol)的许多不同版本,类似于问题How to handle different protocol versions transparently in c++?。我同意继承链可以很好地解决问题。

这就是我在Java中的工作方式:创建一个IParser接口(interface),并具有几个ParserV0ParserV1,...类,它们相互继承并实现IParser

我了解由于某些多重继承和virtual技巧,在C++中可以创建该结构。 这是:在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)


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

我不完全理解为什么要有第一个,但是第二个是有些预料到的,这是我的问题中的主要关注点。

编辑2

我尝试了Scis的建议(声明类和函数的代码相同)
unique_ptr<IParser> getParser() {
    return unique_ptr<IParser>(new ParserV0());
}

auto parser(getParser());

这次,我收到了vtable查找错误,因为它似乎正在IParser中查找函数定义。

最终编辑:

我意识到我的代码有点困惑,而且我缺少一些参数修饰符,因此虚拟的和上载的不匹配。错误很有意义。谢谢您的帮助!

最佳答案

您可以使用抽象基类并按照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;。查看完整示例here

10-06 13:05