有没有办法实现从 c++ 中其他抽象类多重继承的抽象类?

Are there any way to make implementation for abstract class which is multiple inheriting from other abstract classes in c++?

本文关键字:抽象类 其他 多重继承 c++ 实现 有没有      更新时间:2023-10-16

我有两个'接口'类:AbstractAccessAbstractPrintAbstractRun类继承自它们并使用它们的方法。 此外,我有两个接口实现:用于AbstractAccess的访问器和用于AbstractPrint的打印

#include <iostream>                                                                                                                                                                                                
using namespace std;                                                                                                                                                                                               
class AbstractAccess {                                                                                                                                                                                             
public:                                                                                                                                                                                                        
virtual string access (void) = 0;                                                                                                                                                                              
};                                                                                                                                                                                                                 
class AbstractPrint {                                                                                                                                                                                              
public:                                                                                                                                                                                                        
virtual void print (string) = 0;                                                                                                                                                                               
};                                                                                                                                                                                                                 
class AbstractRun : virtual public AbstractAccess, virtual public AbstractPrint {                                                                                                                                  
public:                                                                                                                                                                                                        
void run (void) {                                                                                                                                                                                          
print(access());                                                                                                                                                                                       
}                                                                                                                                                                                                          
};                                                                                                                                                                                                                 
class Accessor : virtual public AbstractAccess {                                                                                                                                                                   
public:                                                                                                                                                                                                        
string access (void){                                                                                                                                                                                      
return name;                                                                                                                                                                                           
}                                                                                                                                                                                                          
void setName(string name) {                                                                                                                                                                                
this->name = name;                                                                                                                                                                                     
}                                                                                                                                                                                                          
private:                                                                                                                                                                                                       
string name;                                                                                                                                                                                               
};                                                                                                                                                                                                                 
class Print: public virtual AbstractPrint {                                                                                                                                                                        
public:                                                                                                                                                                                                        
void print (string s) {                                                                                                                                                                                    
cout << s << endl;                                                                                                                                                                                     
}                                                                                                                                                                                                          
};                                                                                                                                                                                                                 

有没有办法将接口AbstractRun强制转换为它们的实现,或者创建仅使用 AbstractRun 的"run"方法但使用已实现接口的实现类 Run?

虽然你的问题已经解决了,但我进一步研究了这个问题,我想纠正一些关于继承的困惑。

当您是一个类与另一个类具有"是"关系时,将使用继承。派生类应替代要从中继承的类。

在您的情况下,您可以放心地说class Printclass AbstractPrintclass Access同样是class AbstractPrint,因此继承在这里很好。

另一方面,class AbstractRun不是AbstractPrint也不是AbstractAccessAbstractRun简单地处理/组合AbstractPrintAbstractAccess。这种关系应该通过聚合(或组合)来抽象,因为AbstractRun具有指向AbstractRunAbstractPrint的引用/指针。这将使AbstractRun具体,因此让我们将其重命名为Runner.

class Runner
{
public:
// We now need a constructor to set the references.
Runner(AbstractAccess& access, AbstractPrint& print) : 
accessor(access), printer(print) {}
void run (void) {
printer.print(accessor.access());          
}
private:
AbstractAccess& accessor; // has a AbstractAccess
AbstractPrint& printer;   // has a AbstractPrint 
};

现在AccessPrint可以像以前一样定义。

但是,让我们也改进这些:

class Print: public virtual AbstractPrint {
public:
void print (string s) {                                                                                                                                                                                    
cout << s << endl;                                                                                                                                                                                     
}
};

我们不需要虚拟继承。虚拟继承用于解决钻石问题。但是,除了AbstractRunner被做成一个具体的类之外,已经没有钻石了。因此,让我们删除不必要的限定符。

class Accessor : public AbstractAccess {
public:
string access (void){
return name;
}
void setName(string name) {
this->name = name;
}
private:
string name;
}; 
class Print: public AbstractPrint {
public:
void print (string s) {                                                                                                                                                                                    
cout << s << endl;                                                                                                                                                                                     
}
};

此外,如果你有一个兼容 C++11 的编译器,我建议你为覆盖基函数的方法添加override限定符,以便能够确定从基类和非基类中获取的方法。

class Accessor : public AbstractAccess {
public:
string access (void) override { //overrides  AbstractAcces method
return name;
}
void setName(string name) { //does not override. is a method at Accessor level
this->name = name;
}
private:
string name;
}; 

现在初始化一个Runner,我们需要传递具体的访问器和打印机。这可以通过以下方式完成:

// Somewhere in a .cpp - file
Accessor accessor;
Print printer;
Runner runner(accessor, printe);
runner.run(); //will call printer and accessor through the references.