Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Public methods implemented in terms of other public methods of the same class

0 views
Skip to first unread message

Piotr Dobrogost

unread,
Jun 23, 2001, 5:41:18 PM6/23/01
to
Hi !

I wonder if it's good style to implement public methods of a class using
other public methods of the same class ? This gives non minimal interface
but sometimes methods of a class vary much in their complexity and then it
seems to be the best way of implementing more complex methods.

Piotr Dobrogost

[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]

Sef Campstein

unread,
Jun 24, 2001, 6:38:49 AM6/24/01
to
> I wonder if it's good style to implement public methods of a class using
> other public methods of the same class ? This gives non minimal interface
> but sometimes methods of a class vary much in their complexity and then it
> seems to be the best way of implementing more complex methods.

It's neither good nor poor style. You implement it as such when you think
its necessary/wanted.

John Nagle

unread,
Jun 25, 2001, 11:55:33 AM6/25/01
to
Piotr Dobrogost wrote:
>
> Hi !
>
> I wonder if it's good style to implement public methods of a class using
> other public methods of the same class ? This gives non minimal interface
> but sometimes methods of a class vary much in their complexity and then it
> seems to be the best way of implementing more complex methods.

If you take "design by contract", and the idea of class
invariants, seriously, it creates serious problems. The idea
of class invariants is that there are supposed to be statements
that are true whenever control is not inside the class. Public
methods then assume the class invariant to be true when entered,
and must make it true before exiting.

So when you call a public method from inside a class,
you're potentially violating class invariants. Either you're
calling something that doesn't need the class invariants to be
true, or you're calling from a state where the invariants are
are true and it's safe. C++ makes no visible distinction between
those two cases, but they're real and a source of bugs, especially
in concurrent programming. Or when someone maintaining
the code isn't clear on which case a function falls into.

A "strict C++" (something I write on from time to time) would
distinguish those two cases. The compiler shouldn't allow a call
to a public method from a method of its own class. If you have
methods that really can be called from both inside and outside
the class, they should be declared as such, with syntax like

class foo {
public:
void onlycallfromoutside();
public, private:
void oktocallfromanywhere();
private:
fn1;
};

For the other case, where you want to temporarily leave
the class, something like this would be appropriate:

void foo::fn1()
{ oktocallfromanywhere;
public { onlycallfromoutside(); }
}

This new use of the keyword "public" would indicate a temporary
exit from the class. Within the "public" block, public objects
are accessable, but private objects are not.

This idea goes along with adding something like Java's "synchronized"
to C++; entering a "public" block of a synchronized object unlocks
the object, and leaving the public section relocks it.

If C++ ever gets any language-level concurrency support, this
ought to go in at that time. Design by contract isn't popular
enough to justify it, but concurrency is.

With the current syntax, you need to realize that there
are two basic cases involving calls to public methods from
private methods. Not realizing this is a common cause of
trouble in class libraries that are highly interlinked and
stateful, like GUI managers.

John Nagle
Animats

Ivan Vecerina

unread,
Jun 25, 2001, 1:44:12 PM6/25/01
to
Piotr Dobrogost said on 23 Jun 2001 17:41:18 -0400:

>I wonder if it's good style to implement public methods of a class using
>other public methods of the same class ? This gives non minimal interface
>but sometimes methods of a class vary much in their complexity and then it
>seems to be the best way of implementing more complex methods.

I assume that everyone would agree that it makes sense to go beyound
a minimal/orthogonal interface, adding functions which encapsulate and
simplify common call sequences.

However, it is usually a good idea to keep only a minimal interface
within the class itself, and implement the 'extended' interface
using non-member functions.

Key advantages of using non-member functions are:
- they don't break the class' encapsulation (no access to private
members is guaranteed) -- better for maintenance.
- additional extensions are transparent: once you get used to
the fact that f(A&,...) is part of A's interface just as well
as A.f(...), you can transparently have additional headers that
extend A's interface in specific ways.

Consider the standard containers as a typical example: all (most)
algorithms are provided in separate headers, which can be included
when needed (e.g. <algorithm> and <numeric>).
An 'image buffer' class, with separately provided image processing
headers (histogram manipulation, morphological transfors, ...) is
another typical scenario.
If you implement a 3D vector class (3 coordinates), non-mutating
functions such as Angle(v1,v2), DotProduct(v1,v2), etc are also
best provided as helper/non-member functions, even if they lie
in the same header.


I hope this helps,
Ivan

--
Ivan Vecerina, Dr. med. <> http://www.post1.com/~ivec
Software designer for computer assisted surgery systems
--
Brainbench MVP for C++
http://www.brainbench.com

0 new messages