0

It a design question. So, I got an abstract class with a lot of pure virtual methods. Sometimes, I realized I don't need to override these methods, because I'm not interested in these functionnalities. So I changed from pure virtual (=0) to a simple overridable empty method. But now, a child class can override one method but not an other related to it. And it may cause problems... Is there a nice way to force the compiler to say, "if you override this method, you should override this one too !" ?

2 Answers2

2

A simple solution is to keep the abstract class and to have a default child class, like this:

class AbstractMap<TKey, TValue> {
public:
    virtual TValue Get(TKey&& key) = 0;
    virtual bool TryGet(TKey&& key, TValue& result) = 0;
};


class PartiallyImplementedMap<TKey, TValue> : public AbstractMap<TKey, TValue> {
public:
    TValue Get(TKey&& key) override {
        TValue result;
        if (TryGet(std::forward<TKey>(key), result)) {
            return result;
        }
        throw KeyNotFoundException();
    };
};

Now you can inherit from PartiallyImplementedMap and only implement TryGet if the default implementation satisfies you. Otherwise you can inherit from the AbstractMap and implement the entire thing.

freakish
  • 54,167
  • 9
  • 132
  • 169
1

Use mix-in classes.

You could use mix-in classes to adopt implementations of sets of related methods. Read about mix-ins here (even though it's a Python question):

What is a mixin, and why are they useful?

You use mix-ins when...

  • You want to provide a lot of optional features for a class.
  • You want to use one particular feature in a lot of different classes.

which is your case exactly. So, perhaps something like:

class Person { /* ... */ } ;

template <transportation_t MeansOfTransport>
class GetsAroundBy: Person {  /* ... */ };

template <domicile_kind_t DomicileKind>
class LivesIn : Person {  /* ... */ };


class Urbanite : Person, LivesIn<ApartmentBuilding>, GetsAroundBy<Metro> {  /* ... */ };
class SteppePerson : Person, LivesIn<Yurt>, GetsAroundBy<Horse> {  /* ... */ };
einpoklum
  • 118,144
  • 57
  • 340
  • 684
  • It's a nice approach. But in real, It will not help me. In fact, my base class act like an interface. I need to feed a renderer, and I have a lot of rendering technics. The renderer only use the Interface. So I put here only every useful methods, and a set of methods is related to special shader effects (all of them are abstract too). And in my example, I needed some basic renderable stuff without any effects. But I can't modify the Interface just for them, and creating empty methods annoyed me a bit. I'm not sure I can achieve that with your solution. – Sébastien Bémelmans Jun 15 '20 at 11:13