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