Question

I have searched stack overflow but haven't found something that exactly answers my question. I have an interface class which contains only pure virtual functions which I would like to be implemented by classes which derive from this class.

I have an interface that I will call BaseInterface which defines functions that I would like to be overridden in all classes which derive from this interface. In this example, say there is only one pure virtual function called toImplement. I create a class called Base which inherits from BaseInterface and adds some functionality to the inherited pure virtual functions. Base is still an abstract class since it does not implement the functions in BaseInterface.

I have several classes which derive from Base which all benefit from the common functionality of Base but specify what happens when toImplement is run on their instances. These classes should all be concrete and satisfy all the requirements set by BaseInterface. Below I define one of these classes called Derived.

All of this works fine when BaseInterface and Base are not templated. The code compiles and runs fine without defining (1.) or implementing (2.) toImplement in Base.

However I would like toImplement to work with different types. From what I understand it is fine to have pure virtual functions in a templated class. I template BaseInterface and Base on some type T. When I don't define toImplement in Base (1.), I cannot compile since Base doesn't know which toImplement to use in tryUsingImplemented. If I now add the definition to Base, the code pre-compiles but the linker cannot find the implementation of Base::toImplement. Finally, if I both define and implement toImplement in Base (1. and 2.), the code compiles.

I don't like this because I have a dummy implementation of toImplement in Base and I never want this implementation to be run. Additionally, because Base implements toImplement, Derived is no longer required to implement it. This makes BaseInterface useless in my eyes.

Can sombody enlighten me on how to enforce the implementation of toImplement in Derived, without having to implement it in Base first if that is at all possible?

template <typename T>
class BaseInterface {
   virtual void toImplement(T & t) = 0;
};


template <typename T>
class Base : public BaseInterface<T> {
bool m_useImplemented;

public:
   explicit Base(bool useImplemented) : m_usedImplemented(useImplemented) {}

   void tryUsingImplemented(T & t) {
      if (m_useImplemented)
         toImplement(t);
   }  

protected:
   // 1: Defining toImplement pure virtual function in Base
   virtual void toImplement(T & t);
};

// 2. Implementing a version of toImplement in Base which does nothing
template <typename T>
inline void Base<T>::toImplement(T & t) {
   // do nothing
}

class Derived : public Base<int> {
public:
   explicit Derived(bool useImplemented) : Base<int>(useImplemented) {}

protected:
   // 3. implementing toImplement in Derived 
   void toImplement(T & t) {
      std::cout << "Doing stuff for Derived" << std::endl;
   }  

};
Was it helpful?

Solution

For future reference, it would be helpful if you provided the compiler error message.

However, in this case I know. There are two errors in your code:

  1. toImplement is private in BaseInterface.
  2. The lookup in tryUsingImplemented will not look in the base class. You're facing the lookup in dependent bases problem. To fix it, write this->toImplement(t).

OTHER TIPS

You need to declare toImplement as protected in BaseInterface if you intend to call it from a derived class. I have removed all the overriding methods from the derived classes and replaced the parameter type of Derived::toImplement with int, and it compiles fine. The latter is necessary because Derived is not a template, so you need to use the template parameter passed to Base.

  #include <iostream>

  template <typename T>
  class BaseInterface {
  protected:
     virtual void toImplement(T & t) = 0;
  };


  template <typename T>
  class Base : public BaseInterface<T> {
  bool m_useImplemented;

  public:
     explicit Base(bool useImplemented) : m_useImplemented(useImplemented) {}

     void tryUsingImplemented(T & t) {
        if (m_useImplemented)
           toImplement(t);
     }  
  };

  class Derived : public Base<int> {
  public:
     explicit Derived(bool useImplemented) : Base<int>(useImplemented) {}

  protected:
     // 3. implementing toImplement in Derived 
     void toImplement(int & t) {
        std::cout << "Doing stuff for Derived" << std::endl;
     }  

  };
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top