A class Base, which I have no control over, has a function that accepts a member pointer to any class function. It is meant to be used as follows:
class Derived : public Base {
void bindProperties() {
Base::bindProperty("answer", &Derived::getAnswer);
}
int getAnswer() const { return 42; }
};
Some way (that I neither know nor care about), Base stores this pointer and later allows me to call Derived::get("answer") (of course, this is a simplified situation).
The down side is, that we tried to be smart in the past, and used multiple inheritance:
class ICalculator {
virtual int getAnswer() const;
};
template<class T>
class LifeAndUniverseCalculator : public T, public ICalculator {
virtual int getAnswer() const /* override */ { return 42; }
void bindProperties() {
T::bindProperty("answer", &ICalculator::getAnswer); // (*)
}
};
thinking that the multiple inheritance is not bad, as long as we only use it to inherit an interface and only have one "concrete" base class.
The templating is because sometimes we want to derive from Base and sometimes from one of its derived classes (which I also don't have access to) - if that is irrelevant you can pretend I wrote Base instead of T and drop the template.
Anyway, the problem I am having now, is that when I call
LifeAndUniverseCalculator calc;
calc.bindProperties();
int answer = calc.get("answer");
I get gibberish. I figured it may be something with pointers into vtables, so I tried replacing
T::bindProperty("answer", &ICalculator::getAnswer);
by
T::bindProperty("answer", &LifeAndUniverseCalculator::getAnswer);
hoping that it would calculate the offset correctly, but clearly that does not work (as you have figured out by now, I am really second guessing how this all works).
I thought of some options, such as
getting rid of the multiple inheritance and putting everything in
ICalculatordirectly inLifeAndUniverseCalculator(it's the only derived class)creating wrapper functions for all
ICalculatorstuff inLifeAndUniverseCalculator, e.g.LifeAndUniverseCalculator::Calculator_GetAnswerjust callsICalculator::GetAnswer.
I'd like to know
- Preferably, is there a way to fix the line marked with (*) in a simple way?
- If not, what is the best solution (one of the alternatives above, or something else)?
- If I were able to contact the author of class
Baseand they would be willing and able to change their class, what specifically would I need to ask, if you are able to say something sensible based on my description.
If you need a MCVE, there is one which I think captures the problem on IDEOne.
Unknownbut I guess that doesn't change the problem (the idea is probably thatUnknownis zero bytes).