A reason to make virtual members protected instead of private

A

Alf P. Steinbach

virtual win32::WindowHandle parentOrOwnerWindow() const
{
CPPX_IS_OVERRIDE_OF( Base::parentOrOwnerWindow );
// ... impl
}

:)

Caught me by surprise, I'd never thought of that as a reason to make virtuals
protected, even though it's obvious.

But now (at least until C++0x) the FAQ's advice doesn't seem so wrong anymore...


Cheers,

- Alf
 
R

Ron

     virtual win32::WindowHandle parentOrOwnerWindow() const
     {
         CPPX_IS_OVERRIDE_OF( Base::parentOrOwnerWindow );
         // ... impl
     }

:)
OK, I'll bite, what is CPPX_IS_OVERRIDE_OF ?
 
V

Victor Bazarov

Alf said:
* Ron:

Just a macro that checks that the member exists (otherwise compilation
error).

It would be nice to see how it's implemented (and find a way to still
use it). Is it yours?

V
 
A

Alf P. Steinbach

* Victor Bazarov:
It would be nice to see how it's implemented

A straightforward implementation goes like this:

#define CPPX_IS_OVERRIDE_OF( memberSpec ) sizeof( (memberSpec(), 0) )

But since one also needs macros for other numbers of arguments my actual macro
stuff goes like this:

#define CPPX_IS_OVERRIDE_OF( memberSpec ) &memberSpec

// Access issue workarounds, check calls instead of address.
#define CPPX_IS_OVERRIDE_OF_0ARG( memberSpec ) sizeof((memberSpec(),0))
#define CPPX_IS_OVERRIDE_OF_1ARG( memberSpec, a1 ) sizeof((memberSpec(a1),0))
...

I guess it would be nice also with a check for virtuality...

But even this limited checking can/does catch some errors, and serves as
documentation.

Until C++0x.

I think the contortions one has to go through here constitute a defect in the
standard.

I think there should be a difference between data members and routine members
wrt. access: all you can do with a member routine pointer is call the routine,
and when you can do that anyway then it's silly to not be able to obtain the
pointer via a qualified expression.

(and find a way to still use it).
Huh?


Is it yours?

Yeah, but that's like asking whether a piece of music is one's own invention.
All music has already been invented. What we make now is just variations. :)


Cheers,

- Alf
 
A

Alf P. Steinbach

* Alf P. Steinbach:
* Victor Bazarov:

A straightforward implementation goes like this:

#define CPPX_IS_OVERRIDE_OF( memberSpec ) sizeof( (memberSpec(), 0) )

But since one also needs macros for other numbers of arguments my actual
macro stuff goes like this:

#define CPPX_IS_OVERRIDE_OF( memberSpec ) &memberSpec

// Access issue workarounds, check calls instead of address.
#define CPPX_IS_OVERRIDE_OF_0ARG( memberSpec ) sizeof((memberSpec(),0))
#define CPPX_IS_OVERRIDE_OF_1ARG( memberSpec, a1 )
sizeof((memberSpec(a1),0))
...

I guess it would be nice also with a check for virtuality...

But even this limited checking can/does catch some errors, and serves as
documentation.

Until C++0x.

I think the contortions one has to go through here constitute a defect
in the standard.

I think there should be a difference between data members and routine
members wrt. access: all you can do with a member routine pointer is
call the routine, and when you can do that anyway then it's silly to not
be able to obtain the pointer via a qualified expression.



Yeah, but that's like asking whether a piece of music is one's own
invention. All music has already been invented. What we make now is just
variations. :)

Hm, posting that code to the group made me clean it up.


#define CPPX_IS_OVERRIDE_OF_0ARG( memberSpec ) sizeof( (memberSpec(), 0) )
#define CPPX_IS_OVERRIDE_OF_1ARG( memberSpec, a1 ) sizeof( (memberSpec(a1),
0) )
#define CPPX_IS_OVERRIDE_OF_2ARG( memberSpec, a1, a2 ) sizeof( (memberSpec(a1,
a2), 0) )
//...

#define CPPX_IS_OVERRIDE_OF( memberSpec ) CPPX_IS_OVERRIDE_OF_0ARG( memberSpec )



Cheers & hth.,

- Alf
 
A

Alf P. Steinbach

* Alf P. Steinbach:
I think there should be a difference between data members and routine
members wrt. access: all you can do with a member routine pointer is
call the routine, and when you can do that anyway then it's silly to not
be able to obtain the pointer via a qualified expression.

Well, that's bullshit. You can call the routine on the current object (of your
derived class), but not on an object of the base class or other class derived
from that class. It's the same as with access of data members: allowing general
access could let you easily & inadvertently break invariants of other classes.


Cheers & hth.,

- Alf
(Talking to oneself = intelligent conversation, why didn't I think of that B4?)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,159
Messages
2,570,879
Members
47,416
Latest member
LionelQ387

Latest Threads

Top