How to override a function in another base class?

前端 未结 2 1829
面向向阳花
面向向阳花 2021-01-12 04:27

I\'m not exactly sure the terminology to use, but here\'s my example:

class Base {
public:
    virtual void test() = 0;
};

class Mixin {
public:
    virtual         


        
相关标签:
2条回答
  • 2021-01-12 05:00

    You cannot have a class override an unrelated class's virtual function. There are different things you could do to work around this. You can make the mixin a template that derives (virtually) from the type argument and use it as class Example : public virtual Base, Mixin, or you can add code in the final class to dispatch to the mixing:

    void Derived::test() { Mixin::test(); }
    
    0 讨论(0)
  • 2021-01-12 05:03

    You cannot directly have a class override a method not of its base class. But you can sort-of of do it in a roundabout way. I'll present two such approaches - I prefer the second.

    Approach 1

    This is described by Daniel Paul in a post on thinkbottomup.com.au, entitled C++ Mixins - Reuse through inheritance is good... when done the right way.

    In your case, this is what it would look like:

    class Base {
    public:
        virtual void test() = 0;
    };
    
    template <typename T>
    class Mixin : public T {
    public:
        virtual void test() override { /*... do stuff ... */ }
    };
    
    class UnmixedExample : public Base {
        /* definitions specific to the Example class _not_including_
           a definition of the test() method */
    };
    
    using Example = class Mixin<UnmixedExample>;
    
    int main(int argc, char** argv) {
        Example{}.test();
        return 0;
    }
    

    Approach 2: CRTP!

    CRTP is the "Curiously Recurring Template Pattern" - definitely follow that link if you haven't seen it before. With this approach, we'll be using the virtual inheritance specifier to avoid ambiguity, and unlike the previous approach - we will not be reversing the inheritance order of the Mixin and Example classes.

    class Base {
    public:
        virtual void test() = 0;
    };
    
    template <typename T>
    class Mixin : virtual T {
    public:
        virtual void test() override { /*... do stuff ... */ }
    };
    
    class Example : public virtual Base, public virtual Mixin<Base> {
        /* definitions specific to the Example class _not_including_
           a definition of the test() method */
    };
    
    int main(int argc, char** argv) {
        Example{}.test();
        return 0;
    }
    

    Note about both solutions:

    • Ain't it curious how the CRTP keeps recurring all over the place? :-)
    • The code I used is C++11 for pedagogical purposes, but the same would work in C++98.
    0 讨论(0)
提交回复
热议问题