C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Private vs. protected functions for refactoring

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Roy Smith
Guest





PostPosted: Fri Sep 08, 2006 9:20 pm    Post subject: Private vs. protected functions for refactoring Reply with quote



A coworker and I were doing a bit of refactoring yesterday. We found a
hunk of about 10 lines of code that was repeated and pulled it out into its
own little function. I was driving and started typing out the signature as
a private method. My pair said, "No, that should be protected, not
private".

We got into a small discussion about the merits of each. His contention
was that you should make all non-public methods protected unless there's
some good reason not to. I argued that this little hunk of 10 lines of
code didn't seem like something that would be of general use; it was
specific to this refactoring. He argued that somebody might want to
override the (public) function we had started from and would need to access
this little out-factored bit of code.

Any thoughts on how to approach the private-vs-protected issue?

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Markus Grueneis
Guest





PostPosted: Sat Sep 09, 2006 4:15 am    Post subject: Re: Private vs. protected functions for refactoring Reply with quote



Roy Smith schrieb:
Quote:
A coworker and I were doing a bit of refactoring yesterday. We found a
hunk of about 10 lines of code that was repeated and pulled it out into
its
own little function. I was driving and started typing out the signature
as
a private method. My pair said, "No, that should be protected, not
private".

We got into a small discussion about the merits of each. His contention
was that you should make all non-public methods protected unless there's
some good reason not to. I argued that this little hunk of 10 lines of
code didn't seem like something that would be of general use; it was
specific to this refactoring. He argued that somebody might want to
override the (public) function we had started from and would need to
access
this little out-factored bit of code.

Any thoughts on how to approach the private-vs-protected issue?


Well, at least no own thoughts. If I remember correctly, some of Scott
Meyer's C++ books notes that you should use private by default, and only
make it protected when necessary.

I agree with this point and the rationale:
Public methods can have an unknown number of callers.
Private methods only some, all known to you.
Protected methods can ... have an unknown number of callers too.

Additionally, when you have to read your program, and this happens
typically more often than writing, you get the advantage that you don't
need to look very far for calls to private methods. With public and
protected methods you end up using grep or 'find all references', for
each method.


best regards,
-- Markus

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Dave Harris
Guest





PostPosted: Sun Sep 10, 2006 12:11 am    Post subject: Re: Private vs. protected functions for refactoring Reply with quote



roy (AT) panix (DOT) com (Roy Smith) wrote (abridged):
Quote:
We got into a small discussion about the merits of each. His
contention was that you should make all non-public methods protected
unless there's some good reason not to. I argued that this little hunk
of 10 lines of code didn't seem like something that would be of general
use; it was specific to this refactoring. He argued that somebody
might want to override the (public) function we had started from and
would need to access this little out-factored bit of code.

By his argument you should make all variables global in case someone wants
to use them. No.

Making the new function private will help if you need to refactor again in
6 months. You will know you are free to do so with minimal risk of
breaking derived classes. If it's protected, you need to check all client
code for potential callers which is at best inconvenient and at worst,
impossible.

In this case the argument against protected is especially strong. If
someone does override the public function they aren't any worse off then
they were before you refactored. Before, they'd have had to reproduce its
entire functionality, and they still do. If that means copy and pasting
the new private function, so be it. They can decide then whether it would
be better to make it protected and reuse it.

I would only consider making the new function protected if it would be
hard to change later. And then I'd have to consider carefully what the
specification of the protected function was. If it is intended to be
reused, clients need to know how to reuse it properly. It's usually not
worth it.

-- Dave Harris, Nottingham, UK.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Mike
Guest





PostPosted: Sun Sep 10, 2006 3:35 pm    Post subject: Re: Private vs. protected functions for refactoring Reply with quote

Roy Smith wrote:
Quote:
A coworker and I were doing a bit of refactoring yesterday. We found a
hunk of about 10 lines of code that was repeated and pulled it out into its
own little function. I was driving and started typing out the signature as
a private method. My pair said, "No, that should be protected, not
private".

We got into a small discussion about the merits of each. His contention
was that you should make all non-public methods protected unless there's
some good reason not to.

I'd disagree with this as a blanket statement. If anything, I'd make
the general rule as restrictive as possible, i.e. all non-public
methods should be private. It's better to err on the side of
minimizing the visibility of a piece of code; that way you can
remove/change it and not have to worry about breaking a bunch of
derived classes.

Quote:
I argued that this little hunk of 10 lines of
code didn't seem like something that would be of general use; it was
specific to this refactoring.

The hunk of code need not be of general use to the world, just it's
intended audience. For protected functions the intended audience is
classes derived from your base class.

Quote:
He argued that somebody might want to
override the (public) function we had started from and would need to access
this little out-factored bit of code.

If your coworker is correct about this helper function being useful to
derived classes implementing overrided virtual functions, then I'd make
it protected.

Quote:
Any thoughts on how to approach the private-vs-protected issue?

As in most design decisions, it comes down to judgement and trying to
predict how your classes are to be used. When in doubt, though, err on
the side of limiting the visibility/accessibility of your code. You
can always change from private to public later, as you gain
understanding of how your class will be used.

Mike


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Francis Glassborow
Guest





PostPosted: Sun Sep 10, 2006 7:58 pm    Post subject: Re: Private vs. protected functions for refactoring Reply with quote

In article <1157872174.857747.254930 (AT) i3g2000cwc (DOT) googlegroups.com>, Mike
<mhcox (AT) bluezoosoftware (DOT) com> writes
Quote:
As in most design decisions, it comes down to judgement and trying to
predict how your classes are to be used. When in doubt, though, err on
the side of limiting the visibility/accessibility of your code. You
can always change from private to public later, as you gain
understanding of how your class will be used.


Yes, the normal design rule is to provide the minimum access and
visibility necessary for use. In addition delay declarations until the
point of first use (that is for local variables). In general restrict
the scope in which a name can be used as that makes maintenance much
easier.

Another example of this is that free functions should be declared as
either static or in an unnamed namespace until you know that they need
to be used outside a single TU.

It is regrettable that for historical reasons many of the defaults for
C++ (and for C) are the wrong way round. For example, 'variables' should
have been read-only by default, ctors should have been explicit by
default etc.


--
Francis Glassborow ACCU
Author of 'You Can Do It!' and "You Can Program in C++"
see http://www.spellen.org/youcandoit
For project ideas and contributions:
http://www.spellen.org/youcandoit/projects


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
James Kanze
Guest





PostPosted: Sun Sep 10, 2006 11:09 pm    Post subject: Re: Private vs. protected functions for refactoring Reply with quote

Roy Smith wrote:
Quote:
A coworker and I were doing a bit of refactoring yesterday.
We found a hunk of about 10 lines of code that was repeated
and pulled it out into its own little function. I was driving
and started typing out the signature as a private method. My
pair said, "No, that should be protected, not private".

We got into a small discussion about the merits of each. His
contention was that you should make all non-public methods
protected unless there's some good reason not to. I argued
that this little hunk of 10 lines of code didn't seem like
something that would be of general use; it was specific to
this refactoring. He argued that somebody might want to
override the (public) function we had started from and would
need to access this little out-factored bit of code.

Any thoughts on how to approach the private-vs-protected issue?

Protected is, despite the name, part of the public interface
(unless the hierarchy is closed, i.e. you control all of the
derived classes). In practice, I don't think I've ever made
anything in a globally accessable class protected; might as well
make it public, and be done with it.

--
James Kanze (Gabi Software) email: kanze.james (AT) neuf (DOT) fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Niklas Matthies
Guest





PostPosted: Tue Sep 12, 2006 6:48 am    Post subject: Re: Private vs. protected functions for refactoring Reply with quote

On 2006-09-10 18:09, James Kanze wrote:
Quote:
Roy Smith wrote:
:
Any thoughts on how to approach the private-vs-protected issue?

Protected is, despite the name, part of the public interface
(unless the hierarchy is closed, i.e. you control all of the
derived classes).

Once an instance has been created, protected members certainly
aren't part of the public interface for that instance.

-- Niklas Matthies

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
kanze
Guest





PostPosted: Tue Sep 12, 2006 6:21 pm    Post subject: Re: Private vs. protected functions for refactoring Reply with quote

Niklas Matthies wrote:
Quote:
On 2006-09-10 18:09, James Kanze wrote:
Roy Smith wrote:

Any thoughts on how to approach the private-vs-protected issue?

Protected is, despite the name, part of the public interface
(unless the hierarchy is closed, i.e. you control all of the
derived classes).

Once an instance has been created, protected members certainly
aren't part of the public interface for that instance.

If you're talking about runtime, nothing is protected---the
bytes are always accessible. Access control is purely a compile
time mechanism. (I think that there is one exception with
regards to exception handling, but that's it.) If a client can
access something in your class, it's part of your interface.
Making it protected, rather than public, means that the client
has to go to a little more effort to access it, but anything
that is protected still needs a documented contract, which is
guaranteed for all future versions. Just like public.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Niklas Matthies
Guest





PostPosted: Tue Sep 12, 2006 11:22 pm    Post subject: Re: Private vs. protected functions for refactoring Reply with quote

On 2006-09-12 13:21, kanze wrote:
Quote:
Niklas Matthies wrote:
:
Protected is, despite the name, part of the public interface
(unless the hierarchy is closed, i.e. you control all of the
derived classes).

Once an instance has been created, protected members certainly
aren't part of the public interface for that instance.

If you're talking about runtime, nothing is protected---the
bytes are always accessible. Access control is purely a compile
time mechanism. (I think that there is one exception with
regards to exception handling, but that's it.) If a client can
access something in your class, it's part of your interface.

A client like

void f(ClassWithProtectedMembers & foo)
{
foo.protectedMemberFunction(); // won't compile
}

cannot access the protected members *of the instance passed to it*
other than looking at the bytes. The members of this instance are just
as protected from that client as with private. It's certainly not the
same as if they were public.

-- Niklas Matthies

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Lourens Veen
Guest





PostPosted: Wed Sep 13, 2006 4:27 am    Post subject: Re: Private vs. protected functions for refactoring Reply with quote

Niklas Matthies wrote:

Quote:
On 2006-09-12 13:21, kanze wrote:
Protected is, despite the name, part of the public interface
(unless the hierarchy is closed, i.e. you control all of the
derived classes).


A client like

void f(ClassWithProtectedMembers & foo)
{
foo.protectedMemberFunction(); // won't compile
}

cannot access the protected members *of the instance passed to it*
other than looking at the bytes. The members of this instance are
just as protected from that client as with private. It's certainly
not the same as if they were public.

But it can do

#include "classwithprotectedmembers.hpp"

class MyClass : public ClassWithProtectedMembers {
MyClass() {
protectedMemberFunction();
}
};

and you still need to document protectedMemberFunction() in the same
way that you would a public member function. A member function that
is declared protected is not declared public, but it may still be
seen and used by outside code via inheritance, and in that respect
it's "part of the public interface".

Lourens


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Nicola Musatti
Guest





PostPosted: Wed Sep 13, 2006 9:07 pm    Post subject: Re: Private vs. protected functions for refactoring Reply with quote

kanze wrote:
[...]
Quote:
If you're talking about runtime, nothing is protected---the
bytes are always accessible. Access control is purely a compile
time mechanism. (I think that there is one exception with
regards to exception handling, but that's it.)

I think you are forgetting dynamic_cast, which may require access
control to be performed at runtime.

Cheers,
Nicola Musatti


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Niklas Matthies
Guest





PostPosted: Wed Sep 13, 2006 9:42 pm    Post subject: Re: Private vs. protected functions for refactoring Reply with quote

On 2006-09-12 23:27, Lourens Veen wrote:
Quote:
Niklas Matthies wrote:
:
A client like

void f(ClassWithProtectedMembers & foo)
{
foo.protectedMemberFunction(); // won't compile
}

cannot access the protected members *of the instance passed to it*
other than looking at the bytes. The members of this instance are
just as protected from that client as with private. It's certainly
not the same as if they were public.

But it can do

#include "classwithprotectedmembers.hpp"

class MyClass : public ClassWithProtectedMembers {
MyClass() {
protectedMemberFunction();
}
};

and you still need to document protectedMemberFunction() in the same
way that you would a public member function. A member function that
is declared protected is not declared public, but it may still be
seen and used by outside code via inheritance, and in that respect
it's "part of the public interface".

It's part of the "public" interface of the class, but not necessarily
of the instance. James Kanze concluded: "In practice, I don't think
I've ever made anything in a globally accessable class protected;
might as well make it public, and be done with it." I don't agree that
making it public is "as well" - it exposes the member to clients that
get instances passed to them where you (or whoever creates the
instances) might not want that member to be exposed to those clients
for the specific instances you pass to them, all the while permitting
other creators of instances of the class to expose the member in their
instances if they wish to do so.

Incidentally, private virtual member functions are also part of the
"public" interface of a class - might as well make them public... (not!)

-- Niklas Matthies

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Kirit Sælensminde
Guest





PostPosted: Thu Sep 14, 2006 5:14 pm    Post subject: Re: Private vs. protected functions for refactoring Reply with quote

Roy Smith wrote:
Quote:
Any thoughts on how to approach the private-vs-protected issue?

If you are using a language where objects are the only data structures
then this dichotomy stands, but that isn't the case for C++.

I've not seen anybody raise a third option and that is to put the
common code into an anonymous namespace in the implementation file.
This has the added advantage of not requiring a header file change so
is even better for refactoring - much less recompilation.

If the common code can get away with using only the public interface
then this seems the best way to do it. If it needs privilages then it
may be harder, but this depends on what you are doing. For example, you
could pass references to any protected/private members that need to be
changed - breaking encapsulation in this way is of much less concern in
this situation as there will be no access to the function at all
outside the class implementation.

This is what I do most of the time that I want to eliminate common code
within a class. Why clutter up the header at all with private members
when there is no need?


K


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Niklas Matthies
Guest





PostPosted: Fri Sep 15, 2006 1:46 am    Post subject: Re: Private vs. protected functions for refactoring Reply with quote

On 2006-09-14 12:08, kanze wrote:
Quote:
Niklas Matthies wrote:
:
It's part of the "public" interface of the class, but not necessarily
of the instance. James Kanze concluded: "In practice, I don't think
I've ever made anything in a globally accessable class protected;
might as well make it public, and be done with it." I don't agree that
making it public is "as well" - it exposes the member to clients that
get instances passed to them where you (or whoever creates the
instances) might not want that member to be exposed to those clients
for the specific instances you pass to them, all the while permitting
other creators of instances of the class to expose the member in their
instances if they wish to do so.

You seem to miss the point: anyone who wants to call the
functions can, with no trickery.

How so (for an existing instance)?

Quote:
Incidentally, private virtual member functions are also part
of the "public" interface of a class - might as well make them
public... (not!)

There's a big difference: even a derived class cannot call them
(unless it implements them).

Anyway, I don't think it is a big point. I think you agree that
protected functions are part of the "contractual" interface (as
are private virtual functions!).

IME classes have two contractual interfaces, the client interface
and the interface towards derived classes (the latter can generally
be considered to include the former). "Protected" translates into
"private" for the client interface and "public" for the derivation
interface.

Quote:
The important thing, in the context of this thread, is that making
something protected, on the grounds that someone might want to use
it, breaks encapsulation in the same way that making them public
does: it reveals details of the implementation to external parties.

I certainly agree with this part.

Quote:
I probably overstated the issue when saying that "you might as well
make it public", but I was thinking in the context of the original
posting---whether you make the otherwise private function protected
or public, it becomes part of your contractual interface, and ceases
to be an implementation detail.

Yes; that's why I mentioned virtual private members, which are part of
the contractual interface for derivation as well.

-- Niklas Matthies

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Niklas Matthies
Guest





PostPosted: Thu Sep 21, 2006 10:51 pm    Post subject: Re: Private vs. protected functions for refactoring Reply with quote

On 2006-09-15 13:54, kanze wrote:
Quote:
Niklas Matthies wrote:
On 2006-09-14 12:08, kanze wrote:
Niklas Matthies wrote:

It's part of the "public" interface of the class, but not
necessarily of the instance. James Kanze concluded: "In
practice, I don't think I've ever made anything in a
globally accessable class protected; might as well make it
public, and be done with it." I don't agree that making it
public is "as well" - it exposes the member to clients that
get instances passed to them where you (or whoever creates
the instances) might not want that member to be exposed to
those clients for the specific instances you pass to them,
all the while permitting other creators of instances of the
class to expose the member in their instances if they wish
to do so.

You seem to miss the point: anyone who wants to call the
functions can, with no trickery.

How so (for an existing instance)?

I don't quite see the point of the existing instance.

Consider:

class Foo
{
...
protected: void messWithMe();
};

class FooHandler
{
public: void handleFoo(Foo & foo) = 0;
};

Implementations of handleFoo() can't call messWithMe() on the Foo
instances passed to them, because (in general) they don't control what
kind of Foos gets passed to them. It should be obvious that whether
messWithMe() is protected or public makes a fundamental difference
here. From the point of view of handleFoo(), messWithMe() being
protected is pretty much equivalent to messWithMe() being private,
and very different from messWithMe() being public (again, for the
instances passed to handleFoo()).

-- Niklas Matthies

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.