我正在尝试创建一种处理协议的许多不同版本的方法,类似于如何在c++中透明地处理不同的协议版本?的问题。我同意一连串的继承会很好地解决这个问题。
这就是我在Java中所做的工作:创建一个IParser接口,并有几个ParserV0,ParserV1,.类,相互继承并实现IParser。
我理解在C++中创建该结构是可能的,因为有一些多重继承和virtual技巧。这里是:在中,如果我想要一个解析器,我想我可以说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中的函数定义。
最后编辑:
我意识到我的代码有点混乱,我缺少一些参数修饰符,所以虚拟的和覆盖的不匹配。这些错误很有道理。谢谢你的帮助!
发布于 2014-06-11 22:00:37
您可以使用一个抽象基类,并像前面提到的那样,以virtual的形式创建所需的函数,我建议的惟一方法是使用unique_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;
}其中foo声明为:virtual void foo() = 0;。参见完整的示例这里。
发布于 2014-06-11 21:50:05
您的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;
};发布于 2014-06-11 22:15:51
您需要一个抽象工厂,或者一个参数化的工厂方法;这就是jtedit所描述的。通常,在这样做时,您会使构造函数本身受到保护,并且只公开一个工厂方法。查看“四人帮”的创作模式以获得更多信息
模式
https://stackoverflow.com/questions/24173094
复制相似问题