1

My aim is to have a class that inherits from another class in C++ and overloads all of the parents class methods in an identical fashion.

So when a method is called some code is run, the original method is called and a bit more code is run all in the derived class overload method.

class Base
{
  Base() {}
  ~Base() {}

  void base_method()
  {
    // Does something.
  }
}


template<class T>
class ClassWrapper : public T
{
public:
  ClassWrapper(T base) : T( base ) {}
  ~ClassWrapper() {}

  void wrap_function()
  {
    // multithread block {
    // call base method within multithread block.
      this->base_method();
    // }
  }
}

int main()
{
  Base B;
  ClassWrapper<Base> C( B );

  C.base_method();

  return 0;
}

Ideally nothing would be known about the base class but all of its methods could be overridden.

I'm not sure if this is even possible but if it is any suggestions would be great!

  • Why not simply `T().base_method()`? Or are you looking for the [CRTP](https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern)? – πάντα ῥεῖ Jan 17 '21 at 19:32
  • Would that not simply call the base method itself without the code around it necessary to call it in a multithreaded environment? And it would be general so any method of any class can be wrapped in a similar fashion – Eddie Shields Jan 17 '21 at 19:38
  • Which base class? – πάντα ῥεῖ Jan 17 '21 at 19:39
  • I'm not quite sure what you are asking. It sounds like you are trying to make a class which determines which member of its parent type to override based on a template argument? – Andy Newman Jan 17 '21 at 19:39
  • Sorry I can rewrite the question. I would like a class that overloads all of the parents methods but in an identical way. So every method call would involve running some code, calling the original method and running a bit more code – Eddie Shields Jan 17 '21 at 19:43
  • @EddieShields That's usually done the other way round, and called _dependency injection_. – πάντα ῥεῖ Jan 17 '21 at 19:45
  • 2
    Look here: https://stackoverflow.com/a/48408987/1463922 With operator-> it might be possible – PiotrNycz Jan 17 '21 at 20:12
  • In your post, you have "Code runs in threads", but it is not clear what "code" runs in threads. For instance, do you mean the base function? i.e. "this->base_method()" runs in threads? – 2785528 Jan 17 '21 at 21:25
  • @2785528 ```this->base_method()``` would be run in threads. The motivation for overloading the method is so that a multithreaded block can be defined within the overloaded method that the base method is run in – Eddie Shields Jan 17 '21 at 21:38

3 Answers3

1

With inheritance, you might do:

class Base
{
  Base() {}
  virtual ~Base() {}

 virtual void base_method()
  {
    // Does something.
  }
};


class BaseWrapper : public Base
{
public:
  BaseWrapper(Base base) : Bas( base ) {}

  void base_method() override
  {
    // Some code ...
    Base::base_method();
    // Some code ...
  }
}

int main()
{
  Base B;
  BaseWrapper C( B );

  C.base_method();
}
Jarod42
  • 203,559
  • 14
  • 181
  • 302
0

Jarod's answer is a very good one for your question. However, I would like to add an answer more focused on your chosen design rather than the implementation.

Although you said that you want to "overloads all of the parents class methods in an identical fashion", your goal ("the original method is called and a bit more code is run all in the derived class overload method") indicates that it is slightly different.

The first one may indicate inheritance, but the second one may point to factory abstract design pattern (composition over inheritance):

#include<iostream>

class AbstractBar
{
public:
  virtual void bar_method() = 0;
};

class Bar1 : public AbstractBar
{
public:
  void bar_method()  { 
  std::cout << "Bar 1" << std::endl; 
  }
};

class Bar2 : public AbstractBar
{
public:
  void bar_method()  {
    std::cout << "Bar 2" << std::endl;
  }
};

class Foo
{
public:
  Foo(AbstractBar* bar_) : bar(bar_) { }
  void foo_method() { 
      bar->bar_method();
      std::cout << "Foo" << std::endl;
  }
private:
  AbstractBar* bar;
};



int main() {
    Bar1 bar;
    Foo foo(&bar);
    foo.foo_method();
}

Being the output of the code:

Bar 1
Foo

Or a simplified version (based on your needs):

#include<iostream>

class Bar {
public:
  void bar_method()  {
    std::cout << "Bar" << std::endl;
  }
};

class Foo {
public:
  Foo(Bar* bar_) : bar(bar_) { }
  void foo_method() { 
      bar->bar_method();
      std::cout << "Foo" << std::endl;
  }
private:
  Bar* bar;
};

int main() {
    Bar bar;
    Foo foo(&bar);
    foo.foo_method();
}
Jose
  • 3,306
  • 1
  • 17
  • 22
0

Static polymorphism achieved through CRTP (Curiously Recurring Template Pattern) might be beneficial for you. Read more about CRTP here and here.

Imagine you have a Wrapper class like:

template <typename Impl>
class Wrapper {
public:
    Wrapper() {}
    ~Wrapper() {}

    void some_preparation() {
        std::cout << "Wrapper work!" << std::endl;
    }
};

and then you have your actual class like:

class MyFoo : public Wrapper<MyFoo> {
public:
    MyFoo() {}
    ~MyFoo() {}

    void foo() {
        Wrapper::some_preparation();
        std::cout << "Derived work!" << std::endl;
    }
};

and, eventually, you can use above code like:

MyFoo wrappedFoo;
wrappedFoo.foo();

The result would be:

Wrapper work!
Derived work!
NutCracker
  • 11,485
  • 4
  • 44
  • 68