473,395 Members | 2,010 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,395 software developers and data experts.

How do I implement final in C++

Hi,

I think my problem is indeed "how to implement something like java's
final in C++"

The long version....

I have an abstract base class which is inherited by several concrete
classes.
I have a group of methods that I'd like to implement in the base class
and would like
to mandate that the client should send those messages directly to the
base class
(and not thru its derived classes). I guess that is similar to "final"
in Java...

How do I enforce such policies...

Thanks
Jul 19 '05 #1
14 23092
Medi Montaseri wrote:
I think my problem is indeed "how to implement something like java's
final in C++"

The long version....

I have an abstract base class which is inherited by several concrete
classes.
I have a group of methods that I'd like to implement in the base class
and would like
to mandate that the client should send those messages directly to the
base class
(and not thru its derived classes). I guess that is similar to "final"
in Java...

How do I enforce such policies...


Read /Effective C++/, then do these three things:

- not write 'virtual' on the methods
- write a sternly worded comment
- write no other methods in the heirarchy with the same name

In C++, you don't pay for what you don't use. Not writing 'virtual' states
you do not intend to use a slot in the secret vtable (or whatever) for this
function, so you won't pay for it.

You need the last item because if you had two functions with the same name,
they would hide each other. Pointers, references or instances to one type
would bind that message at compile time to to one method, and pointers,
references or instances to another type would bind to another method. So if
you change the pointer or reference type, but not the ultimate instance, you
could silently change which type the compiler selects. Write more
defensively, to decrease the odds of a mistake like that: Don't give
different things the same name (unless they are, in fact, virtual overrides
of each other).

The cost of a real "final" in a strictly compiled language like C++ would be
too high.

--
Phlip
http://www.c2.com/cgi/wiki?TestFirstUserInterfaces
Jul 19 '05 #2
Medi Montaseri wrote:
Hi,

I think my problem is indeed "how to implement something like java's
final in C++"

The long version....

I have an abstract base class which is inherited by several concrete
classes.
I have a group of methods that I'd like to implement in the base class
and would like
to mandate that the client should send those messages directly to the
base class
(and not thru its derived classes). I guess that is similar to "final"
in Java...

How do I enforce such policies...

Thanks


Youi can call the baseclass method expicitely:

class b
{
virtual void method() {}
};

class d1: public b
{
void method();
};

class d2: public d1
{
void method();
};

int main( int argc, char* argv[])
{
d2 var;
var.b::method(); // calls b's 'method' function
}

hdh,
marc

Jul 19 '05 #3
mo*******@netscape.net (Medi Montaseri) wrote in message news:<c9**************************@posting.google. com>...
Hi,

I think my problem is indeed "how to implement something like java's
final in C++"

The long version....

I have an abstract base class which is inherited by several concrete
classes.
I have a group of methods that I'd like to implement in the base class
and would like
to mandate that the client should send those messages directly to the
base class
(and not thru its derived classes). I guess that is similar to "final"
in Java...

How do I enforce such policies...

Thanks


Adding to the OP's question:
_____
| c1 | virtual void a() = 0;
|_____| vritual void b() = 0;
^
___|___
__|__ __|__
implements b | c2 | | c3 | both implements a
virtual void b();|_____| |_____| virtual void a();
^
___|____
__|__ __|__
| c4 | | c5 | NOT supposed to REimplement a
|_____| |_____| both implement b

If I have the situation shown above, is there a way to prevent the
implementers of classes derived from c3 (c4 and c5 in the diagram) to
accidentally reimplement method a? By a way I mean a compiler error
like the one I suppose is shown in Java when one tries to reimplement
a method declared as final.

Thanks

Marcelo Pinto
Jul 19 '05 #4
Karl Heinz Buchegger <kb******@gascad.at> wrote in message news:<3F***************@gascad.at>...
Marcelo Pinto wrote:


Adding to the OP's question:
_____
| c1 | virtual void a() = 0;
|_____| vritual void b() = 0;
^
___|___
__|__ __|__
implements b | c2 | | c3 | both implements a
virtual void b();|_____| |_____| virtual void a();
^
___|____
__|__ __|__
| c4 | | c5 | NOT supposed to REimplement a
|_____| |_____| both implement b

If I have the situation shown above, is there a way to prevent the
implementers of classes derived from c3 (c4 and c5 in the diagram) to
accidentally reimplement method a? By a way I mean a compiler error
like the one I suppose is shown in Java when one tries to reimplement
a method declared as final.


The question is: Why would you want to do this?
Suppose I derive a class d6 from c5 and I absolutely need to reimplement
a(), because the one in c3 doesn't fit my needs. What should I do then?


In that situation you should derive from c1, not from c3.

Best regards,

Marcelo Pinto.
Jul 19 '05 #5
On 2 Aug 2003 00:26:10 -0700, mo*******@netscape.net (Medi Montaseri) wrote:
Marc Schellens <m_*********@hotmail.com> wrote in message news:<3F**************@hotmail.com>...
Medi Montaseri wrote:
> Hi,
>
> I think my problem is indeed "how to implement something like java's
> final in C++"
>
> The long version....
>
> I have an abstract base class which is inherited by several concrete
> classes.
> I have a group of methods that I'd like to implement in the base class
> and would like
> to mandate that the client should send those messages directly to the
> base class
> (and not thru its derived classes). I guess that is similar to "final"
> in Java...
>
> How do I enforce such policies...
>
> Thanks


Youi can call the baseclass method expicitely:

class b
{
virtual void method() {}
};

class d1: public b
{
void method();
};

class d2: public d1
{
void method();
};

int main( int argc, char* argv[])
{
d2 var;
var.b::method(); // calls b's 'method' function
}

hdh,
marc


Thanks Marc...but I'm looking for a more defensive approach.....you
are showing
an honor system by which the client is sending a message to the right
class/object.

I'm looking for a way to enforce that no other derived classes can
inherit this given
method of base class.


Ugh. If a derived class does not _inherit_ a method, then that method
does not exist in the derived class; that property is not what you
want unless your requirements list is a dynamic one created on the fly
to be non-implementable. A Java 'final' method is of course inherited.

The key property of a Java 'final' method is that it cannot be
overridden by a derived class.

In C++ the nearest technical feature is a non-virtual method. A non-
virtual C++ method can not be overridden (like a Java 'final' method),
and it is inherited (like a Java 'final' method). In short, it's what
you want.

Perhaps your confusion stems from the fact that a derived class can
redefine the method:
* Do you understand the difference between redefine (a non-virtual
method) and override (a virtual method)?
Now, on another tack, more in support of the view that C++ is lacking
in this respect.

The main difference between a non-virtual and a final method, which
you haven't said anything about as a requirement, is that in C++
this method cannot be virtual in base classes of the class where it's
defined. Where you want to _introduce_ 'finality' on a method in an
inheritance chanin you have, in C++, no technical feature that directly
supports that. In that case you have to use C++ to implement the
feature if you want it enforced at compile time, e.g. usign containment
instead of inheritance.

Jul 19 '05 #6


Marcelo Pinto wrote:

Karl Heinz Buchegger <kb******@gascad.at> wrote in message news:<3F***************@gascad.at>...
Marcelo Pinto wrote:


Adding to the OP's question:
_____
| c1 | virtual void a() = 0;
|_____| vritual void b() = 0;
^
___|___
__|__ __|__
implements b | c2 | | c3 | both implements a
virtual void b();|_____| |_____| virtual void a();
^
___|____
__|__ __|__
| c4 | | c5 | NOT supposed to REimplement a
|_____| |_____| both implement b

If I have the situation shown above, is there a way to prevent the
implementers of classes derived from c3 (c4 and c5 in the diagram) to
accidentally reimplement method a? By a way I mean a compiler error
like the one I suppose is shown in Java when one tries to reimplement
a method declared as final.


The question is: Why would you want to do this?
Suppose I derive a class d6 from c5 and I absolutely need to reimplement
a(), because the one in c3 doesn't fit my needs. What should I do then?


In that situation you should derive from c1, not from c3.


And thereby reimplementing all the usefull functionality in c3 :-)

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 19 '05 #7


Medi Montaseri wrote:

Karl Heinz Buchegger <kb******@gascad.at> wrote in message news:<3F***************@gascad.at>...
Marcelo Pinto wrote:


Adding to the OP's question:
_____
| c1 | virtual void a() = 0;
|_____| vritual void b() = 0;
^
___|___
__|__ __|__
implements b | c2 | | c3 | both implements a
virtual void b();|_____| |_____| virtual void a();
^
___|____
__|__ __|__
| c4 | | c5 | NOT supposed to REimplement a
|_____| |_____| both implement b

If I have the situation shown above, is there a way to prevent the
implementers of classes derived from c3 (c4 and c5 in the diagram) to
accidentally reimplement method a? By a way I mean a compiler error
like the one I suppose is shown in Java when one tries to reimplement
a method declared as final.


The question is: Why would you want to do this?
Suppose I derive a class d6 from c5 and I absolutely need to reimplement
a(), because the one in c3 doesn't fit my needs. What should I do then?


That is a valid concern, if a given implementation does not fit the
need,
a derived class should be able to override (hide) the one implemented
in base.

However in my original posting, I was looking for a way to say

message foo() can only be send to Abstract_Bass_Class (eg
AbstractBase->foo())
and message foo() can not be send to any Derived_Classes....as in


But the question is: Do you really, really, really know that nobody
in the future will never want to do this and handle foo() on it's own.

You are not a magician and I am not. It often happens and it will
happen in the future, that someone might want to extend a class by
deriving from it in a way that you never thought of.

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 19 '05 #8
Medi Montaseri wrote:
from programming.
That is if the interface calls for certain functionality, it is
desirable for the tools (ie
programming languages) to accommodate the designer to set forth rules
and policies and
not to be at the mercy of notes, comments, honor systems and such....


Then you need a language other than C++. Other languages do more to
"help" prevent the programmer from screwing up, but the philosophy of
C++ is to give the programmer as much latitude and as many options as
possible, even if it increases the likelihood of making a mistake.

--
Mike Smith

Jul 19 '05 #9
On 4 Aug 2003 21:09:54 -0700, mo*******@netscape.net (Medi Montaseri) wrote:
Perhaps I should explain what I want to achieve and ask for the way in
C++.
That is a _very_ good idea.
I want to implement an interface (an abstract base class). I
also want this interface to maintain a container (a list of
ptr to objects of its derived classes). I'll also implement
a factory method in the base that produces instances of
its derived classes. eg

Employee->getNewEmployee().
Employee->listEmployees()
Technically that would be

Employee::getNew()
Employee::list()

Since I can not instantiate the abstract base, I figured I'll
implement a private static _employeeList as in
static map < string &, Employee *> _employeeList ;
Where getNewEmployee() factory method will populate.
OK.
But if I do something like

Employee *emp;
Employee *Bob = emp->getNewEmployee("Bob");
Technically this would be

Employee* Bob = Employee::getNew( "Bob" );
emp->listEmployees(); // I want this to work
Employee::list()
Bob->listEmployees(); // I don't want to allow this, as instance
Bob does not have access
// to the static data member.
(1)
In C++ an instance does have access to static members of its class.

(2)
Why on Earth do you _really_ want to disallow this?

(3)
If you really want or need to it's easily done by moving the factory
and the list out of the Employee class. Some possibilites are

* Free-standing functions.

* Separate class EmployeeFactory.

* Nested class Employee::Factory.
And that is why I was looking for a way to mandate that listEmployee()
message should only
be send to the interface and not any derived classes (or their
instances).


That isn't 100% meaningful; but see above.

Jul 19 '05 #10

Medi Montaseri <mo*******@netscape.net> wrote in message
news:c9**************************@posting.google.c om...
"Phlip" <ph*******@yahoo.com> wrote in message

news:<bg********@dispatch.concentric.net>...
Medi Montaseri wrote:
I think my problem is indeed "how to implement something like java's
final in C++"

The long version....

I have an abstract base class which is inherited by several concrete
classes.
I have a group of methods that I'd like to implement in the base class
and would like
to mandate that the client should send those messages directly to the
base class
(and not thru its derived classes). I guess that is similar to "final"
in Java...

How do I enforce such policies...


Read /Effective C++/, then do these three things:

- not write 'virtual' on the methods
- write a sternly worded comment
- write no other methods in the heirarchy with the same name


Thanks for the reply....

Your suggestion 1 is granted, ie the method will not be a virtual
method in the base class.
Your suggestion 2 is also granted, but this is too week. I'm trying to
stop the programmer
who is about to inherit from base to even move a finger, ie stop
him/her at compile time.
Writing comments and honor systems only goes so far...
Your guesstion 3 is too restricted, I can not controll what some
derived class author
would like to call his/her method. If base implements foo() as a
concrete
method, then if a derived class implements a similar name method (ie
foo() again),
the client of derived object will get derived::foo() which is ok...I
just don't want the
client to send a message to a derived object and the call get routed
to the base.
One reason is what if I have a private static data member in my base
abstract class
and I don't want any derived objects inheriting my foo(), which then
the call would
fail as the derived object would not have access to the base private
data member.

I think the idea behind an abstract base class is to seperate design
from programming.
That is if the interface calls for certain functionality, it is
desirable for the tools (ie
programming languages) to accommodate the designer to set forth rules
and policies and
not to be at the mercy of notes, comments, honor systems and such....


Then I think you need a more 'hand-holding' language.
C++ (and C) is like a gun in a holster on your belt.
It's *your* responsibility to make sure it points where
it should before pulling the trigger. Ever hear the
phrase 'shoot yourself in the foot'? :-)

-Mike

Jul 19 '05 #11
Karl Heinz Buchegger <kb******@gascad.at> wrote in message news:<3F**************@gascad.at>...
Marcelo Pinto wrote:

Karl Heinz Buchegger <kb******@gascad.at> wrote in message news:<3F***************@gascad.at>...
Marcelo Pinto wrote:
>
>
> Adding to the OP's question:
> _____
> | c1 | virtual void a() = 0;
> |_____| vritual void b() = 0;
> ^
> ___|___
> __|__ __|__
> implements b | c2 | | c3 | both implements a
> virtual void b();|_____| |_____| virtual void a();
> ^
> ___|____
> __|__ __|__
> | c4 | | c5 | NOT supposed to REimplement a
> |_____| |_____| both implement b
>
> If I have the situation shown above, is there a way to prevent the
> implementers of classes derived from c3 (c4 and c5 in the diagram) to
> accidentally reimplement method a? By a way I mean a compiler error
> like the one I suppose is shown in Java when one tries to reimplement
> a method declared as final.

The question is: Why would you want to do this?
Suppose I derive a class d6 from c5 and I absolutely need to reimplement
a(), because the one in c3 doesn't fit my needs. What should I do then?


In that situation you should derive from c1, not from c3.


And thereby reimplementing all the usefull functionality in c3 :-)


As a matter of fact no. Because the functionality you wanted to
specialize is exactly the one was specialized by c3. Thus there is not
an usefull functionality in c3 for your new class.

And the question remains. Is there a way to prevent users of this
hierarchy from reimplement method a below class c3 other than with a
comment?

Thanks,

Marcelo Pinto
Jul 19 '05 #12


Marcelo Pinto wrote:

Karl Heinz Buchegger <kb******@gascad.at> wrote in message news:<3F**************@gascad.at>...
Marcelo Pinto wrote:

Karl Heinz Buchegger <kb******@gascad.at> wrote in message news:<3F***************@gascad.at>...
> Marcelo Pinto wrote:
> >
> >
> > Adding to the OP's question:
> > _____
> > | c1 | virtual void a() = 0;
> > |_____| vritual void b() = 0;
> > ^
> > ___|___
> > __|__ __|__
> > implements b | c2 | | c3 | both implements a
> > virtual void b();|_____| |_____| virtual void a();
> > ^
> > ___|____
> > __|__ __|__
> > | c4 | | c5 | NOT supposed to REimplement a
> > |_____| |_____| both implement b
> >
> > If I have the situation shown above, is there a way to prevent the
> > implementers of classes derived from c3 (c4 and c5 in the diagram) to
> > accidentally reimplement method a? By a way I mean a compiler error
> > like the one I suppose is shown in Java when one tries to reimplement
> > a method declared as final.
>
> The question is: Why would you want to do this?
> Suppose I derive a class d6 from c5 and I absolutely need to reimplement
> a(), because the one in c3 doesn't fit my needs. What should I do then?

In that situation you should derive from c1, not from c3.
And thereby reimplementing all the usefull functionality in c3 :-)


As a matter of fact no. Because the functionality you wanted to
specialize is exactly the one was specialized by c3. Thus there is not
an usefull functionality in c3 for your new class.


Granted. Not in this example. But add a function c() to c3 and the situation
changes ... I then want a class d6, derived from c5, with all the functionality
of c5 and c3 and yet have a special handling of a().


And the question remains. Is there a way to prevent users of this
hierarchy from reimplement method a below class c3 other than with a
comment?


No. For exactly this reason: You never know what another programmer
might want to do with your code.

As it turned out (as usual), the OP was heading to a design error without
recognizing it, tried to invent or use a feature which is not in the language
to overcome a problem he will not have if his design is correct.

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 19 '05 #13
mo*******@netscape.net (Medi Montaseri) wrote in message news:<c9**************************@posting.google. com>...
Hi,

I think my problem is indeed "how to implement something like java's
final in C++"

The long version....

I have an abstract base class which is inherited by several concrete
classes.
I have a group of methods that I'd like to implement in the base class
and would like
to mandate that the client should send those messages directly to the
base class
(and not thru its derived classes). I guess that is similar to "final"
in Java...

How do I enforce such policies...

Thanks


The answer lies, in essence, with the friend operator and the way C++
constructs virtually derived objects. Consider the following:

template <typename T>
class DerivationLock
{
friend T;

private:
// This can only be called by this class or a friend!
DerivationLock() {};
}

class FinalClass : virtual public DerivationLock<FinalClass>
{
...
}

Now we can merrily create an instance of FinalClass as it is a friend
of the base and so can call its private constructor. But see what
happens when we try and derive from FinalClass:

class Usurper : public FinalClass
{
...
}

The constructor of Usurper will try and call the private constructor
for DerivationLock directly, without going through the construction of
FinalClass (this is what virtual inheritance does). Obviously, this
is not allowed by the compiler as Usurper is not a friend of
DerivationLock (note that friendship is not inherited). Hence we
can't derive from FinalClass.

Hope that addresses your problem.
Jul 19 '05 #14
Write Java not C++.

Or write C not C++ or Java. Then you can just give the victims a library.

But you still can't stop 'em writing their own code that uses a C library.
mo*******@netscape.net (Medi Montaseri) wrote in message news:<c9**************************@posting.google. com>...
Hi,

I think my problem is indeed "how to implement something like java's


etc etc etc
Jul 19 '05 #15

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

Similar topics

0
by: Anthony Baxter | last post by:
To go along with the 2.4a3 release, here's an updated version of the decorator PEP. It describes the state of decorators as they are in 2.4a3. PEP: 318 Title: Decorators for Functions and...
11
by: Sridhar | last post by:
Hi, I am doing my undergrade CS course. I am in the final year, and would like to do my project involving Python. Our instructors require the project to have novel ideas. Can the c.l.p people...
10
by: Bezalel Bareli | last post by:
I know I have seen some threads on the subject long time ago and it was using a virtual base class ... in short, what is the nicest way to implement the Java final class in c++ Thanks.
193
by: Michael B. | last post by:
I was just thinking about this, specifically wondering if there's any features that the C specification currently lacks, and which may be included in some future standardization. Of course, I...
5
by: nobody | last post by:
With Visual C++ 2005 beta 2, I get the below compling error for the following code. I think this error is not acceptable to me because int::typeid is a constant and is known to compiler when...
14
by: My4thPersonality | last post by:
Has the fact that both Java and C# are garbage collected, and C++ in not, anything to do with the fact that there is no language item to prevent a class from being inherired from? I once read that...
2
by: h3lp | last post by:
Hi, i'm a newbie in XML world :) Currently my group is doing final project which is about DRM. From our research it appears that we need to implement ODRL because ODRL enable us to set permission,...
3
by: no1zson | last post by:
I have been working on this application for weeks now, it is almost finished, but I am getting errors that I am unable to work through. Can someone look at my code and see if anything stands out...
0
by: shailesh prajap | last post by:
Hello, Right now i am making social network project. so, i have to implement functionality like facebook post and write comment on each post. basically i use datalist to fill post from post...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

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.