1

I have seen Is it possible to replace a method at runtime in C/C++?, but I am something of a C++ newbie, and so cannot yet see how (and if) it applies to my case, so I'd like to try asking with my example.

In the example below, assume classes MyBase, A1, and A2, come from some library, and I'm using them in my main:

// g++ -std=c++11 -o test.exe test.cpp

#include <iostream>

using namespace std;

class MyBase {
public:
  MyBase() { }
  ~MyBase() { }
  int getBaseVal(int inval) {
    return inval + 5;
  }
};

class A1 : public MyBase {
public:
  A1() : MyBase() { }
  ~A1() { }
  int getVal(int inval) {
    return getBaseVal(inval) + 10;
  }
};

class A2 : public A1 {
public:
  A2() : A1() { }
  ~A2() { }
  int getVal(int inval) {
    return getBaseVal(inval) + 20;
  }
};


int main() {
  A1 _a1 = A1(); A2 _a2 = A2();
  cout << "A1 for 10: " << _a1.getVal(10) << endl;
  cout << "A2 for 10: " << _a2.getVal(10) << endl;
  return 0;
}

Now, let's say I would like to leave this library untouched, but I've discovered a bug in MyBase::getBaseVal, in that the right value returned should be inval + 6; instead of the given inval + 5;. So, nothing complicated, but access to the input arguments of the method is needed.

So do I have an option, to define a new function, say:

int getNewBaseVal(int inval) {
  return inval + 6;
}

.. and then somehow "replace" the old MyBase::getBaseVal:

  • On a class level (that is, MyBase would be "patched"), such that all subsequent instantiations of A1 and A2 will ultimately use the getNewBaseVal when their getVals are called;
  • On an object level, such that only a particular instantiation of, say, A1 as object (like _a1) would ultimately use the getNewBaseVal when its getVal is called;

... by writing some code at the start of the main function?

Community
  • 1
  • 1
sdaau
  • 36,975
  • 46
  • 198
  • 278
  • 4
    So you fully read a previous Q&A asking whether it's possible to replace a method ......... then you asked the exact same question again? – Lightness Races in Orbit Sep 30 '15 at 15:58
  • @LightnessRacesinOrbit - well, yes; as one, I'm not sure whether the "runtime" qualifier applies here (I'd like to make a "patch" once at start, and not change it dynamically, maybe there are relaxed criteria for that?); secondly, if polymorphism is the answer, I don't really have an idea how I would go about extending only `MyBase`, without having to also extend `A1`, `A2` and the whole inheritance chain - which is what I'd like to avoid, and the main reason for my question. – sdaau Sep 30 '15 at 16:02
  • 3
    Well the long and short of it is that you can't. Get the library author to fix the bug, and build your own forked and fixed version of it in the meantime. – Lightness Races in Orbit Sep 30 '15 at 16:03
  • Thanks for that @LightnessRacesinOrbit - feel free to post that as an answer, I'll accept it. Cheers! – sdaau Sep 30 '15 at 16:04

2 Answers2

4

The long and short of it is that you can't; at least, not within the given constraints (which rule out various sub-optimal hacks, such as Andrey's!).

Get the library author to fix the bug, and build your own forked and fixed version of it in the meantime.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
0

I'd like to suggest you to create an adapter class and use it as the base class for A and B

class MyBaseAdaptor: public MyBase
{
    using MyBase::MyBase; // Inherit constructors

public:
    int getBaseVal(int inval)  // Hide the old method
    {
        // your code here
    }
};

But it is better to fix the library.

Andrey Nasonov
  • 2,619
  • 12
  • 26
  • 1
    Thanks for that, @AndreyNasonov - but then the `A1`, `A2` classes still wouldn't know about `MyBaseAdaptor`, unless I recode them too, so they inherit from `MyBaseAdaptor`; is that correct? – sdaau Sep 30 '15 at 16:07
  • 1
    Yes, `class A1 : public MyBaseAdaptor` – Andrey Nasonov Sep 30 '15 at 16:08
  • 1
    @AndreyNasonov: The OP is pointing out, quite correctly, that he'd have to do this for _each and every class in the inheritance tree_, which is not desired. You have not answered the question per the given constraints. – Lightness Races in Orbit Sep 30 '15 at 16:12