Re: querying for virtual method existence
On Jul 12, 6:05 pm, rabin shahav <sha...@gmail.com> wrote:
Hi All,
I've a base class and about 500 derivatives classes. No, i'm not
confusing class instances with class definitions... and don't ask how
we end up having so many classes...
There are few methods which can be eliminated from the whole hierarchy
cone if at run time the base class could "know" if a certain method
was overridden.
Bottom line - i need the code for Foo::wasBarReDefinedNew
your help is well appreciated.
Rabin.
class Foo {
public:
virtual int bar(double, int, char ) ;
virtual bool wasBarReDefined()const=0;
bool wasBarReDefinedNew()const
{ // i need the code here...
return ????
}
};
class Bar1 : public Foo { // about 200 more Bar classes....
public:
virtual bool wasBarReDefined()const{return true;}
virtual int bar(double, int, char );
//....
};
class Baz1 : public Foo { // about 300 more Baz classes....
public: // no override of 'bar'
virtual bool wasBarReDefined()const{return false;}
///....
};
I like stuff like this because it makes me feel dirty :)
That said, I should put the standard disclaimer that this is totally
compiler dependent, and there's no standard conformant way to do what
you want. The following works on most versions of MSVC however, and
relies on the fact that stream << operators accept function pointers
and send the corresponding virtual function table index to the
stream. And did I mention you should never do this? :)
#include <iostream>
#include <sstream>
typedef void** VTBL_;
template<class C, class R>
int vtable_index(R (C::*ptr)())
{
std::stringstream stream;
int index;
stream << ptr;
stream >> index;
return index - 1;
}
template<class T>
VTBL_ vtbl_ptr()
{
T t;
VTBL_ result = reinterpret_cast<VTBL_>(&t);
return reinterpret_cast<VTBL_>(*result);
}
template<class Derived>
class base
{
typedef base<Derived> Type;
public:
virtual void foo()
{
std::cout << "base::foo" << std::endl;
}
bool was_foo_redefined()
{
int base_index = vtable_index(&Type::foo);
VTBL_ base_vtbl = vtbl_ptr<Type>();
VTBL_ cur_vtbl = vtbl_ptr<Derived>();
void* base_foo = base_vtbl[base_index];
void* cur_foo = cur_vtbl[base_index];
return (base_foo != cur_foo);
}
};
class redefined : public base<redefined>
{
public:
virtual void foo()
{
std::cout << "derived::foo" << std::endl;
}
};
class not_redefined : public base<not_redefined>
{
public:
};
int main(int argc, char** argv)
{
redefined* r = new redefined();
not_redefined* n = new not_redefined();
bool s_false = n->was_foo_redefined();
bool s_true = r->was_foo_redefined();
}
Note that this also doesn't work if base has a pure virtual function.
There might be a way around that, but I haven't thought about it much.
And for the record, I do NOT recommend doing anything like this in
production code, but I'm not sure it's any worse than having 500
subclasses, so what the heck right?
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]