有没有办法为抽象类实现多个继承自c ++中其他抽象类的实现?

问题描述 投票:-4回答:1

我有两个'接口'类:AbstractAccessAbstractPrint,以及从它们继承并使用它们的方法的AbstractRun类。另外,我有两个接口实现:AbstractAccess的访问器和AbstractPrint的Print

#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中的接口转换为它们的实现或者创建实现类Run只会使用AbstractRun的'run'方法但是实现了接口?

c++ abstract-class multiple-inheritance
1个回答
0
投票

虽然你已经解决了你的问题,但我还是深入研究了这个问题,并且我想解决一些关于继承问题的困惑。

当您的类与另一个类具有“是”关系时,将使用继承。派生类应该是您继承的类的替代。

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

另一方面,class AbstractRun不是AbstractPrint,也不是AbstractAccessAbstractRun简单地处理/组合了AbstractPrintand AbstractAccess。这个关系应该用聚合(或组合)抽象,因为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.
© www.soinside.com 2019 - 2024. All rights reserved.