Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Preventing Virtual Method Implementation in C++

I have the following class hierarchy in C++:

class Base {
    virtual void apply() = 0;
};

class Derived : public Base {
    virtual void apply() {
        // implementation here that uses derived_specialty
    }

    virtual void derived_specialty() = 0;
};


class Implementation : public Derived {   
    virtual void derived_specialty() {
        // implementation
    }
};

I'd like to guarantee that classes at the level of Implementation don't supply their own implementation of apply, and that they only implement derived_specialty. Is there any way to guarantee that classes inheriting from Derived will not implement apply, so that the Derived::apply implementation is used? My understanding is that in C++, a method made virtual in the Base class is virtual all the way down the inheritance hierarchy, but if there are any tricks in C++ to accomplish, I'd be interested in hearing about them.

I'm always surprised by the things that are allowed by C++, so I thought it was worth asking. :)

like image 498
James Thompson Avatar asked Nov 26 '22 22:11

James Thompson


2 Answers

You could make Implementation a delegate class rather than a specialization of Derived

class Derived : public Base
{
    Derived()

    void apply() 
    {
        //whatever, delegate to impl class instance
        impl->apply_specialization();
    }


    Impl* impl;
};

class Impl : public WhateverImplInterface
{
      void apply_specialization(){}
};

Then the implementation doesn't have access to the apply function and is separated from the hierarchy. The Derived class is then parameterized by an instance of Impl class.

like image 119
user21714 Avatar answered Nov 29 '22 13:11

user21714


You can kind of do it by composition:

class Base {
    virtual void apply();
};

class Derived : public Base {

    class IImplementation {
        virtual void derived_specialty() = 0;
    };

    IImplementation& m_implementation;

    Derived(IImplementation& implementation)
        : m_implementation(implementation)
    {}

    virtual void apply() {
        // implementation here that uses m_implementation.derived_specialty
    }

};


class Implementation : Derived::IImplementation {   
    virtual void derived_specialty() {
        // implementation
    }
};

Other classes can still subclass Derived and override the apply method, but your Implementation class is no longer one of these classes.

like image 39
ChrisW Avatar answered Nov 29 '22 13:11

ChrisW