Derived class implementing multiple interfaces wit

2020-03-26 04:49发布

问题:

I'm getting a compile error when I try to compile my code. The error is this:

multi.cc: In function ‘int main()’:
multi.cc:35: error: cannot declare variable ‘mdc’ to be of abstract type ‘MostDerivedClass’
multi.cc:27: note:   because the following virtual functions are pure within ‘MostDerivedClass’:
multi.cc:13: note:  virtual int Interface2::common_func()
multi.cc:36: error: request for member ‘common_func’ is ambiguous
multi.cc:13: error: candidates are: virtual int Interface2::common_func()
multi.cc:21: error:                 virtual int InterimClass::common_func()

And here is my code:

class Interface1 {
public:
    virtual int common_func() = 0;
    virtual ~Interface1() {};
};

class Interface2 {
public:
    virtual int common_func() = 0;
    virtual int new_func() = 0;
    virtual ~Interface2() {};
};


class InterimClass : public Interface1 {
public:
    virtual int common_func() {
        return 10;
    }
};


class MostDerivedClass : public InterimClass, public Interface2 {
public:
    virtual int new_func() {
        return 20;
    }   
};

int main() {
    MostDerivedClass mdc;
    int x = mdc.common_func();
    cout << "The value = " << x << endl;    

    Interface2 &subset_of_funcs = dynamic_cast<Interface2 &>(mdc);
    x = subset_of_funcs.common_func();
}

My questions:

  • How do I tell the compiler that common_func() is already implemented by the InterimClass which is a base class of MostDerivedClass?

  • Is there another way to fix my problem? What I would really like to do is to be able to also call common_func from Interface2. I'm working with some legacy code with a huge amount of methods in Interface1. In my new code, I only want to call a small set of these Interface1 functions, plus a few that I need to add.

回答1:

You need to define a common_func() anyway in MostDerivedClass to satisfy your inheritance from Interface2

you can try something like

virtual int common_func() {
    return InterimClass::common_func();
}

This is most useful if you cannot change the first Interface1

If you want a real inheritance relationship between your classes you need to follow Lol4t0 advice. Extract a superclass from Interface1, and make Interface2 subclass of this newly created class. Example :

class RootInterface{
public :
    virtual int common_func() = 0;
    virtual ~RootInterface(){}
};

class Interface1 : public virtual RootInterface{
public:
    virtual ~Interface1() {};
};

class Interface2 : public virtual RootInterface{
    public:
    virtual int new_func() = 0;
    virtual ~Interface2() {};
};

class InterimClass : public Interface1 {
    public:
    virtual int common_func() {
        return 10;
    }
};

class MostDerivedClass : public InterimClass, public Interface2 {
public:
    virtual int new_func() {
        return 20;
    }
};


回答2:

Add an override in MostDerivedClass, and from it call InterimClass::common_func().



回答3:

First of all, I don't really understand the sense of your code.

You need to know that only Interface1::common_func is implemented.

Why don't you make Interface2 inherit from Interface1? I guess you want for both common_func methods to be equal.

Example code (uses polymorphism):

class Interface1 
{
public:
    virtual int common_func() = 0;
    virtual ~Interface1() {};
};

class Interface2 : public Interface1 {
public:
    virtual int common_func() = 0;
    virtual int new_func() = 0;
    virtual ~Interface2() {};
};

class InterimClass : public Interface2 {
    public:
        virtual int common_func() {
            return 10;
        }
};

class MostDerivedClass : public InterimClass {
public:
    virtual int new_func() {
        return 20;
    }
};

int test_func()
{
    Interface1 * i1 = new MostDerivedClass;
    int x = i1->common_func();
    cout << "The value = " << x << endl;

    Interface2 * i2 = new MostDerivedClass;
    x = i2->common_func();

    return 0;
}


回答4:

Let the second interface be derived from the first interface, remove the declaration of virtual int common_func() = 0; from the second interface, & use the keyword virtual to guide the compiler to the implementation.

class Interface1 {
public:
    virtual int common_func() = 0;
    virtual ~Interface1() {};
};

class BaseClass : public virtual Interface1 {
public:
    virtual int common_func() {
        return 10;
    }
};

class Interface2 : public virtual Interface1{
public:
    virtual int new_func() = 0;
    virtual ~Interface2() {};
};

class DerivedClass : public virtual BaseClass, public virtual Interface2 {
public:
    virtual int new_func() {
        return 20;
    }   
};