【问题标题】:Are there any way to make implementation for abstract class which is multiple inheriting from other abstract classes in c++?有什么方法可以实现从 C++ 中的其他抽象类多重继承的抽象类?
【发布时间】:2019-03-12 20:01:42
【问题描述】:

我有两个“接口”类: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 Run: public virtual AbstractRun, public virtual Accessor, public virtual Print {...}
  • @Beta 非常感谢。你已经正确理解并且你的食谱就像一个魅力。如果第二部分正在工作,则不需要第一部分。谢谢你更多的时间。

标签: c++ abstract-class multiple-inheritance


【解决方案1】:

虽然您的问题已经解决,但我对此进行了深入研究,并想澄清一些关于继承的困惑。

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

在您的情况下,您可以放心地说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.

【讨论】:

    猜你喜欢
    • 2014-02-17
    • 2013-08-25
    • 2013-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多