[comp.lang.c++] How to detect virtual functions whether inherited or redefined?

ishii@hexard.co.jp (Koji Ishii) (03/20/91)

     Are there way to detect whether a virtual function is redefined
in its sub classes or not?  Say, there is a class A:

class A {
public:
	virtual int action();
	int check(){ if (this->action != A::action){ ... } }
};

In A::check(), I tried to activate a button if only action() is
redefined in its sub classes, but my g++ 1.39.0 did not work as I
expected.  I wanted to know whether action() is redefined or not
*before* calling action(), and am afraid of using another virtual
function such as action_redefined_P() as I may redefine action() and
forget to redefine action_redefined_P().

     Is this impossible in C++, or am I going something wrong?  Or are
there any better solution?
--
----------------------------------
  Koji Ishii  Hexard Inc., Tokyo, Japan. <Do not mail me, please>

sakkinen@jyu.fi (Markku Sakkinen) (04/08/91)

In article <ISHII.91Mar20230510@batman.hexard.co.jp> ishii@hexard.co.jp (Koji Ishii) writes:
>
>     Are there way to detect whether a virtual function is redefined
>in its sub classes or not?  Say, there is a class A:
>
>class A {
>public:
>	virtual int action();
>	int check(){ if (this->action != A::action){ ... } }
>};
>
> [...]   but my g++ 1.39.0 did not work as I
>expected.  [...]
>
>     Is this impossible in C++, or am I going something wrong?  Or are
>there any better solution?

Funny, this simple question is over two weeks old, but I could see
no answer posting yet on our system.  (We may have lost some news
because of problems in networking software - upgrading to a new version
of SunOS is usually a terrifying experience.)

It was hard to find an answer in the Annotated Reference Manual;
surprisingly, the index gave only little help with this question.
According to Section 8.1c of the ARM, it seems that the right-hand
side of the comparison requires and explicit address-of operator:
    &A::action
but it is taken to mean a "pointer to member", which would actually
better be called 'offset to member'.  This offset is the same for
'A::action' and any redefined 'action' in a derived class!

It would seem that the only possibility to obtain your purpose
is to have an _object_ of class A through which you can get 
the address of the function itself.  But how can you you already
have such an object in the midst of the definition of A?
Well, use an auxiliary friend class somewhat like this:

class A {
public:
	virtual int action();
	int check();
// whatever other members you have
};
class Aux {
	friend class A;
	static A base;
	static int check (A* pal)
		{ return (pal->action != base->action); }
};
int A::check() { if (Aux::check (this)){ ... } }

Obviously, you will need similar checking functions in both A and Aux
for every additional member function about whose redefinition you
want to know.

WARNING: I have no idea whether any or all existing implementations
will handle even this example as you would expext.

Markku Sakkinen
Department of Computer Science and Information Systems
University of Jyvaskyla (a's with umlauts)
PL 35
SF-40351 Jyvaskyla (umlauts again)
Finland
          SAKKINEN@FINJYU.bitnet (alternative network address)