Ways to detect whether a C++ virtual function has been redefined in a derived class
Solution 1:
You can't check for override of virtual function portably.
You need to bring the knowledge to the Solver
, preferably via type as opposed to run-time flag.
One (type-based) way is to check for presence or absence of a interface, via dynamic_cast
.
A probably better way is to provide overloads of solve function, in your case the Solver
constructor.
Probably better advice could be given if you provided a more concrete description of the problem. It does remind of typical situation where someone (1) needs to solve some problem P, (2) envisions technical approach X as a solution to P, (3) discovers that X doesn't cut it, and (4) asks how to make X work for a vague description of P, or even for some unrelated problem Q. The details of original problem P will often suggest a much better solution than X, and the problems of making X work, irrelevant to solving P.
Solution 2:
For future reference, it turns out that GCC provides this extension: http://gcc.gnu.org/onlinedocs/gcc/Bound-member-functions.html which allows checking if a method was overridden with
(void*)(obj.*(&Interface::method)) != (void*)(&Interface::method)
ICC supports this extension officially, clang's docs don't mention it but the code works and even compiles without the warning.
MSVC doesn't support this, though, so there's that.
Also, it appears to not work with methods defined in the header (i.e. inline) in a separate library if you link to a different version of the library where the implementation has changed. If I interpret the standard correctly, this is undefined behaviour (changing the implementation that is) but if the implementation stays the same, then the address should be unique too. So don't do that with inline methods.
Solution 3:
After only finding results that link to gcc's PMF extension, I thought there must be a proper way to do so.
I found a solution without any hacks and is at least tested to work on gcc & llvm:
#include <iostream>
#include <typeinfo>
struct A { virtual void Foo() {} };
struct B : public A { void Foo() {} };
struct C : public A { };
int main() {
std::cout << int(typeid(&A::Foo) == typeid(&A::Foo)) << std::endl;
std::cout << int(typeid(&A::Foo) == typeid(&B::Foo)) << std::endl;
std::cout << int(typeid(&A::Foo) == typeid(&C::Foo)) << std::endl;
return 0;
}
http://ideone.com/xcQOT6
PS: I actually use it in a CEventClient system. So you derive your class from CEventClient and if it overrides an event method it will automatically 'link' the event.
Solution 4:
Even though this probably is somehow possible, I would advice not doing it. You are:
- Violating the OOP principles. If you are given a general class/interface, you should not check for implementation details. This increases dependency between classes and is exactly the opposite of what OOP was designed for.
- Duplicating code. Considering that you use the constants that would be otherwise returned by the Equation class.
- Obfuscating code. Many conditions with type checks will make your program look ugly.
- Probably doing a premature optimization. There is almost no speed difference between executing a virtual function call and a condition. Have you run your profiler to check if it's the virtual functions that are the bottleneck? It is almost never the case in a well designed application/library.