我正在尝试创建一种方法来处理协议(protocol)的许多不同版本,类似于问题How to handle different protocol versions transparently in c++?。我同意继承链可以很好地解决问题。
这就是我在Java中的工作方式:创建一个IParser
接口(interface),并具有几个ParserV0
,ParserV1
,...类,它们相互继承并实现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。