繁体   English   中英

有什么方法可以实现抽象类,它是从 C++ 中的其他抽象类多重继承的?

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

我有两个“接口”类: AbstractAccessAbstractPrint ,以及从它们继承并使用它们的方法的AbstractRun类。 另外,我有两个接口实现:用于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 Print是一个class AbstractPrintclass Access同样是一个class AbstractPrint ,因此继承在这里很好。

在另一方面, class AbstractRun不是AbstractPrint和既不是AbstractAccess AbstractRun只是处理/组合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.

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM