Finalizing virtual methods

D

Dave Rudolf

Hi all,

Suppose that I have a class (let's call the class A) with a virtual method.
I then define a subclass (B), which could potentially be extended by some
other subclass (say, C). So, A <- B <- C. I want to prevent C from
redefining the virtual method in same manner as how a "final" method in Java
cannot be overridden.. Is there some way to do this in C++?

Dave.
 
V

Victor Bazarov

Dave Rudolf said:
Suppose that I have a class (let's call the class A) with a virtual method.
I then define a subclass (B), which could potentially be extended by some
other subclass (say, C). So, A <- B <- C. I want to prevent C from
redefining the virtual method in same manner as how a "final" method in Java
cannot be overridden.. Is there some way to do this in C++?

No. Why would you want to do that?
 
J

John Harrison

Dave Rudolf said:
Hi all,

Suppose that I have a class (let's call the class A) with a virtual method.
I then define a subclass (B), which could potentially be extended by some
other subclass (say, C). So, A <- B <- C. I want to prevent C from
redefining the virtual method in same manner as how a "final" method in Java
cannot be overridden.. Is there some way to do this in C++?

Dave.

Documentation, its the only way. Or choose another language, perhaps
beginning with the letter J.

john
 
D

Dave Rudolf

Victor Bazarov said:
No. Why would you want to do that?

Security. In my case, B requires the virtual method to behave in a certain
way. If C overrides the method, it could break the expected behavior.
 
V

Victor Bazarov

Dave Rudolf said:
Security. In my case, B requires the virtual method to behave in a certain
way. If C overrides the method, it could break the expected behavior.

Then your 'B' class cannot be derived from (or your supposition that
it "could potentially be extended" is incorrect). To make 'B' non-
derivable, declare its constructor private.

Otherwise, just document the behaviour and your requirement not to have
it overridden. If somebody willingly implements the overrider in 'C'
class after you told them not to, it's not your responsibility.

C++ does not have any means to prohibit anything, only to protect
from unintentional errors. I am fairly sure that if you are in
control of 'A' and 'B' classes, you can change their interface or the
implementation so that the behaviour that needs to be hidden is, in
fact, simply hidden.

BTW, the 'final' specifier in Java is not something they should be
proud of, IMO.

Victor
 
D

Dave Rudolf

Security. In my case, B requires the virtual method to behave in a certain
way. If C overrides the method, it could break the expected behavior.

Then your 'B' class cannot be derived from (or your supposition that
it "could potentially be extended" is incorrect). To make 'B' non-
derivable, declare its constructor private.


Ah, but there may still be need to inherit from that class, either to merely
gain its functionality (which is not really good coding practice -- leads to
spagetti inheritance) or because it is overriding other methods.
C++ does not have any means to prohibit anything, only to protect
from unintentional errors. I am fairly sure that if you are in
control of 'A' and 'B' classes, you can change their interface or the
implementation so that the behaviour that needs to be hidden is, in
fact, simply hidden.

"unintentional errors" can be defined rather braodly.
BTW, the 'final' specifier in Java is not something they should be
proud of, IMO.

I see it as no different than type checking or the const modifier: that is
to have the compiler prevent the coder from doing something that they
shouldn't be doing.

Dave.
 
V

Victor Bazarov

Dave Rudolf said:
Security. In my case, B requires the virtual method to behave in a certain
way. If C overrides the method, it could break the expected behavior.

Then your 'B' class cannot be derived from (or your supposition that
it "could potentially be extended" is incorrect). To make 'B' non-
derivable, declare its constructor private.


Ah, but there may still be need to inherit from that class, either to merely
gain its functionality (which is not really good coding practice -- leads to
spagetti inheritance) or because it is overriding other methods.


Again, if you intend to override other member functions, then all
member functions declared virtual are fair game. If you don't
want the programmer deriving from your file to override certain
methods, _all_you_have_ is documentation. Simple as that. No
need to discuss it any further. There is no 'final' (or any of
its potential analoques) in C++.

C++ cannot prevent people from doing stupid things. It's rather
impossible in the language which is already as complex as C++ is.
And attempting to "simplify" it in certain areas can lead to...
....well, Java.
"unintentional errors" can be defined rather braodly.

OK, errors are almost always unintentional, I'll give you that. But
what else do you have against my statement? There is no way in hell
to make your compiler not let you, say, access class private members
if you have access to the class header, just add your 'friend'
statement there, for example. There is no way to protect from never
'delete'ing a pointer that was allocated using 'new' (although some
did implement a garbage collector for C++), or from 'delete'ing the
same pointer twice. Sacrifices have to be made. That's why machines
writing programs in C++ are still losing in numbers to people.
I see it as no different than type checking or the const modifier: that is
to have the compiler prevent the coder from doing something that they
shouldn't be doing.

I am not going to discuss Java in a C++ newsgroup. Do you have any
other C++ question?

V
 
D

David Harmon

Security. In my case, B requires the virtual method to behave in a certain
way. If C overrides the method, it could break the expected behavior.

AKA design by contract. Some people get one level of it by making all
virtual functions private, and called by a non-virtual function in the
base class that enforces the pre- and post-conditions expected. Hard to
cover the whole inheritance hierarchy that way, though. Maybe one level
would be some help in your case.

Full language support for design by contract is one of the often
requested features for a future version of C++.
 
D

Dylan Nicholson

Dave Rudolf said:
Security. In my case, B requires the virtual method to behave in a certain
way. If C overrides the method, it could break the expected behavior.

If B requires the virtual method to behave in a certain way, then why
is it virtual? I'm not suggesting a case like this couldn't possibly
exist, but I'm curious in the exact case that concerns you.

Dylan
 
D

Dave Rudolf

Victor Bazarov said:
Again, if you intend to override other member functions, then all
member functions declared virtual are fair game. If you don't
want the programmer deriving from your file to override certain
methods, _all_you_have_ is documentation. Simple as that. No
need to discuss it any further. There is no 'final' (or any of
its potential analoques) in C++.

Okay, so I understand what I want to do cannot be done in C++, and yes that
the need for such a feature is a relatively rare. The discussion has moved
to the more philosphical note below.
C++ cannot prevent people from doing stupid things. It's rather
impossible in the language which is already as complex as C++ is.
And attempting to "simplify" it in certain areas can lead to...
...well, Java.

Of course, a compiler cannot read the mind of the coder, and too much
compiler intervension can restrict what the coder can do (e.g. garbage
collection leads to wasted CPU at the expense of coding ease). But, that
does not mean that we should give up on trying to help the coder. Especially
when systems are getting larger and more complex, with larger development
teams, programmers need all the help that they can get. What happens in a
natural language when some new thing arises in society? We evolve the
language to adequately differentiate between the new thing and what was
there before. C++ evolves very slowly, which is good -- it doesn't
incorporate every trendy feature that comes along. But, as far as the ANSI
language goes, it has been rather stagnant the last decade or so. Perhaps it
is time to start moving again.
OK, errors are almost always unintentional, I'll give you that. But
what else do you have against my statement? There is no way in hell
to make your compiler not let you, say, access class private members
if you have access to the class header, just add your 'friend'
statement there, for example. There is no way to protect from never
'delete'ing a pointer that was allocated using 'new' (although some
did implement a garbage collector for C++), or from 'delete'ing the
same pointer twice. Sacrifices have to be made. That's why machines
writing programs in C++ are still losing in numbers to people.

I guess what I am arguing is a matter of taste. One person's unintentional
error is another person's regular playing ground.
I am not going to discuss Java in a C++ newsgroup. Do you have any
other C++ question?

I think it's fair to bring up other languages in comparison to the current
one. Granted, I know that it is taboo to say the J-word in this group :).

Dave.
 
R

Ron Natalie

David Harmon said:
AKA design by contract. Some people get one level of it by making all
virtual functions private, and called by a non-virtual function in the
base class that enforces the pre- and post-conditions expected. Hard to
cover the whole inheritance hierarchy that way, though. Maybe one level
would be some help in your case.

I don't know if this helps this at all. Access control doesn't have any effect
on overriding. Even private virtual methods can be overridden.
 
D

David Harmon

I don't know if this helps this at all. Access control doesn't have any effect
on overriding. Even private virtual methods can be overridden.

Yes, that's the point. You still want derived classes to be able to
override the virtual function. You just want to restrict the behavior
of the overriding function. The base class restricts it by checking
preconditions, calling the virtual, then checking postconditions, all in
a public non-virtual function. Foreign classes cannot call the virtual
directly, but only via the base class interface.

That may not be everything the O.P. was asking for, but it's a start.
 

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

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,045
Latest member
DRCM

Latest Threads

Top