473,321 Members | 1,708 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,321 software developers and data experts.

How to determine if virtual function in base class is overriden?

I have a base class, PadRcv, with virtual functions. User code
will derive from this class and possibly supply it's own functions
to override the base class virtual functions. How can I test that
a user-defined class has overriden the virtual function in the
base class?

I have code like this which compiles with gcc 2.95.4:

Attrib Implicits(PadRcv *obj){
Attrib accum = 0;
PadRcv *padrcv;

if( !obj ) return 0;
char* (PadRcv::*pmfa)(char *) = &PadRcv::kbd;
void (PadRcv::*pmfb)() = &PadRcv::userclose;
if( obj->*pmfa != &PadRcv::kbd ) accum |= ACCEPT_KBD;
if( obj->*pmfb != &PadRcv::userclose ) accum |= USERCLOSE;
return accum;
}

With gcc 3.4.4, I get the following errors:

pad.C: In function `Attrib Implicits(PadRcv*)':
pad.C:27: error: invalid use of non-static member function
pad.C:28: error: invalid use of non-static member function
*** Error code 1

There is plenty of documentation on the net for pointers to member
functions and virtual functions but nothing seems to cover this
particular area.

Dec 20 '06 #1
6 2797
<no*******@gmail.comwrote:
>I have a base class, PadRcv, with virtual functions. User code
will derive from this class and possibly supply it's own functions
to override the base class virtual functions. How can I test that
a user-defined class has overriden the virtual function in the
base class?
Cannot some debugger interfaces unwind the class structure
and expose its hierarchy, including information like this?

I think, anyway, this is a tools question if the problem
can be solved by manual examination.

Steve
Dec 20 '06 #2
On Dec 20, 7:38 am, noel.h...@gmail.com wrote:
I have a base class, PadRcv, with virtual functions. User code
will derive from this class and possibly supply it's own functions
to override the base class virtual functions. How can I test that
a user-defined class has overriden the virtual function in the
base class?
Why would you like to know, I find that it kind of goes against the
whole idea of virtual functions, you don't need to know if it's the
base's function or the derived's.

--
Erik Wikström

Dec 20 '06 #3

no*******@gmail.com wrote:
I have a base class, PadRcv, with virtual functions. User code
will derive from this class and possibly supply it's own functions
to override the base class virtual functions. How can I test that
a user-defined class has overriden the virtual function in the
base class?
You can't "test" if the user overode the virtual function other than by
observing the result. What you can do is provide a pure virtual member
function in the base class which means the user can't compile a
derivative class unless that pure virtual is indeed implemented.
>
I have code like this which compiles with gcc 2.95.4:

Attrib Implicits(PadRcv *obj){
Attrib accum = 0;
PadRcv *padrcv;

if( !obj ) return 0;
char* (PadRcv::*pmfa)(char *) = &PadRcv::kbd;
void (PadRcv::*pmfb)() = &PadRcv::userclose;
You could identify the type of object through RTTI where <typeinfo>
will let you resolve the type of the object at the pointer, if any.

#include <typeinfo>
....
int Implicits(PadRcv *obj){
if( !obj ) return 0;
std::cout << "the object at *obj is of type:";
std::cout << typeid(*obj).name() << std::endl;
...
}

Judging from the error you are getting and the code here, something
else is going on. In particular, you are *not* attempting to call a
member function on the object, but rather on the class - hence the
error about "invalid use of non-static member function". That should be
expected at this point.
if( obj->*pmfa != &PadRcv::kbd ) accum |= ACCEPT_KBD;
if( obj->*pmfb != &PadRcv::userclose ) accum |= USERCLOSE;
return accum;
}
Also, treating blocks of char arrays as data is begging for trouble.
>
With gcc 3.4.4, I get the following errors:

pad.C: In function `Attrib Implicits(PadRcv*)':
pad.C:27: error: invalid use of non-static member function
pad.C:28: error: invalid use of non-static member function
*** Error code 1

There is plenty of documentation on the net for pointers to member
functions and virtual functions but nothing seems to cover this
particular area.
Dec 20 '06 #4
* no*******@gmail.com:
I have a base class, PadRcv, with virtual functions. User code
will derive from this class and possibly supply it's own functions
to override the base class virtual functions. How can I test that
a user-defined class has overriden the virtual function in the
base class?

I have code like this which compiles with gcc 2.95.4:

Attrib Implicits(PadRcv *obj){
Attrib accum = 0;
PadRcv *padrcv;

if( !obj ) return 0;
char* (PadRcv::*pmfa)(char *) = &PadRcv::kbd;
void (PadRcv::*pmfb)() = &PadRcv::userclose;
if( obj->*pmfa != &PadRcv::kbd ) accum |= ACCEPT_KBD;
if( obj->*pmfb != &PadRcv::userclose ) accum |= USERCLOSE;
return accum;
}

With gcc 3.4.4, I get the following errors:

pad.C: In function `Attrib Implicits(PadRcv*)':
pad.C:27: error: invalid use of non-static member function
pad.C:28: error: invalid use of non-static member function
*** Error code 1

There is plenty of documentation on the net for pointers to member
functions and virtual functions but nothing seems to cover this
particular area.
Note that the first comparision is essentially

obj->*(&PadRcv::kbd) != &PadRcv::kbd

and one does not expect the two sides to have the same types since the
left hand side is in a sense dereferenced.

But it's worse: there's /no/ type in C++ for the result of "->*" and
".*". The only thing you can do with such a result is to use it as the
operand for the function call operator. I.e., apply (...).

One technical solution is to test for the presence of an interface
rather than presence of a virtual function, i.e. using dynamic_cast.

But in general a better approach is to design the base class so that it
doesn't need to know anything about its derived classes, and to not try
to be overly clever or do evil premature micro-optimization.

Now for details.

1. All uppercase for constants is a Java'ism.
Don't do it. Reserve all uppercase for macros.
2. More naming: "Implicits", "kbd" and "userclose" form a set of
names with no apparent naming convention.
3. Even more about names. PadRcv is just as silly as early assembly
language HLT, or Unix creat. Save one keystroke, for what?
4. The Attrib enumeration. In standard C++ you need to cast from
int to Attrib.
5. char* as argument is ungood. Use char const*. Or better,
std::string const&.
6. PadRcv* as argument is ungood. At least use PadRcv const*. But
better use PadRcv const&.
7. Kudos: your code caused MSVC 7.1 to ICE. ;-)

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Dec 20 '06 #5
I think I need to explain the rationale for needing to know
when the user derived class has overriden the virtual
function in the base class. The application is a window
on which there are various `layers'; a layer is a user-defined
object that is built on (derived from) a base layer class.

The application allows the user defined classes to supply
a keyboard handling function, and a function used to close,
the current object. If the user derived class has not supplied
either of these then a suitable message is printed. In the
case of a keyboard handler, the application will signal
whether the currently selected object on the screen will
accept input from the keyboard. The object in question
might be the whole layer, or just a selected line in the
layer.

I suppose this could be coded in a different way, but I
am working from very old C++ code. In the good old days
one could use function pointers, and it's this that I am
trying to port. As I pointed out, the code works in gcc 2.95.4.

The various replies, and my writing this response, make
me realise that I probably don't need to care about
whether the base class virtual function has been
overriden. The base class function prints something
suitable when invoked, and that is enough. If a user
class supplies a function, then it just does it's job.

By the way, upper-case for constants pre-dates Java by
a couple of decades. Dennis Ritchie's coding style can't
really be faulted. The code I'm working on is, well, vintage,
to say the least.

Many thanks for the responses.

Noel Hunt

Dec 20 '06 #6
* no*******@gmail.com:
>
By the way, upper-case for constants pre-dates Java by
a couple of decades.
Java got the convention from C, where it was used for macros, and of
course used for manifest constants defined as macros (C didn't
originally have 'const').

Since Java doesn't have a language-supported preprocessor only the
aspect of constantness survived.

And that is at odds with original purpose in C, to keep the "namespace"
of macros separate since macros don't respect scopes.

Dennis Ritchie's coding style can't really be faulted.
If what you mean is that, a couple of decades ago (we're talking 1970's
here) Dennis used all uppercase for manifest constants defined as
macros, then true, using all uppercase for macros can't really be
faulted, and that's what everyone should do -- see this group's FAQ as
well as Bjarne Stroustrup's FAQ. However, Dennis also used all
uppercase for typedef'ed names, and lowercase for functionlike macros.
And that can (really!) be faulted... From a modern point of view with
20-20 hindsight, that is. At that time the source code for a program
was considerably less than today, when included headers are counted, and
furthermore I suspect that Dennis had at least some degree of control
over the contents of those headers -- which we today don't have.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Dec 20 '06 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
by: Stuart Golodetz | last post by:
Hi, I've got a minor casting issue which I need to check about (marked // <--). I was trying to do a static_cast on it (which didn't work, though I'm not sure why this should be the case?) I...
11
by: Josh Lessard | last post by:
Hi all. I'm maintaining a C++ program and I've come across a nasty piece of code that works, but I just don't understand why. I'm not actually this part of the program, but I really want to know...
24
by: Shao Zhang | last post by:
Hi, I am not sure if the virtual keyword for the derived classes are required given that the base class already declares it virtual. class A { public: virtual ~A();
37
by: WittyGuy | last post by:
Hi, I wonder the necessity of constructor and destructor in a Abstract Class? Is it really needed? ? Wg http://www.gotw.ca/resources/clcm.htm for info about ]
10
by: Martin Vorbrodt | last post by:
Example code in one of my books intrigues me: class B { public: B* Clone() const { B* p = DoClone(); assert(typeid(*p) == typeid(*this)); return p; }
32
by: Adrian Herscu | last post by:
Hi all, In which circumstances it is appropriate to declare methods as non-virtual? Thanx, Adrian.
15
by: Philipp | last post by:
Hello I don't exactly understand why there are no static virtual functions. I would have liked something like this: class Base{ static virtual std::string getName(){ return "Base"; } }
4
by: David Zha0 | last post by:
Hi, "when we call a virtual method, the runtime will check the instance who called the method and then choose the suitable override method, this may causes the performance drop down", is this...
1
by: donesbon | last post by:
Hi ... I'm faily new to C++ but have 6 years experience in other languages ... still C++ and the syntax puzzles me a great deal ... I have the following problem ... I have a base class with a...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.