By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
429,426 Members | 1,729 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 429,426 IT Pros & Developers. It's quick & easy.

data members as "protected"?

P: n/a
Act
Why is it suggested to not define data members as "protected"?

Thanks for help!

Jul 22 '05 #1
Share this Question
Share on Google+
28 Replies


P: n/a
Act posted:
Why is it suggested to not define data members as "protected"?

Thanks for help!


Why is it suggested to not walk around alone at night?

Thanks for help!
-JKop
Jul 22 '05 #2

P: n/a
"Act" <ot***@hash.com> wrote in message
news:Q6*********************@bgtnsc04-news.ops.worldnet.att.net...
Why is it suggested to not define data members as "protected"?


IMO that's too general an advice to be meaningful. From
where did you get this suggestion?

Specifying a member (data or function) as 'protected'
means that derived classes have direct access to them.
Use 'protected' if that's what you need.

-Mike
Jul 22 '05 #3

P: n/a
"Act" <ot***@hash.com> wrote:
Why is it suggested to not define data members as "protected"?


The assumption is that the member data was put in this particular class
because there was some invariant that has to be maintained and this
class is the one designated to maintain it.

Obviously, given the case above, the class can't ensure the invariant if
it can't control access to the data.

What if the assumption doesn't hold? In that case, you might as well
make the data public.
Jul 22 '05 #4

P: n/a
Act wrote:
Why is it suggested to not define data members as "protected"?


Because derived classes depending on it will be too dependent on their
bases. Why is that a problem? Because if youy want/need to change your
base class design you cannot. Because derived class (you may not even know
about) depend on those protected members to be there and not to change. And
experience shows that data members do change.

--
WW aka Attila
:::
Don't believe everything you think.
Jul 22 '05 #5

P: n/a
"Act" <ot***@hash.com> wrote in message
news:Q6*********************@bgtnsc04-news.ops.worldnet.att.net...
Why is it suggested to not define data members as "protected"?


Some suggest that, some don't. I generally avoid protected data members,
but some people don't mind. For instance, the answers in the FAQ
(http://www.parashift.com/c++-faq-lite/) under "Inheritance basics",
questions 8 and 9 lean towards protected data. I must admit that the
paragraph deriding "purists" is a bit, er, melodramatic.

--
David Hilsee
Jul 22 '05 #6

P: n/a
> > Why is it suggested to not define data members as "protected"?

IMO that's too general an advice to be meaningful. From
where did you get this suggestion?


Stroustrup for one (referring to protected data in particular). See section
15.3.1.1 in http://www.research.att.com/~bs/3rd.html
Jul 22 '05 #7

P: n/a
"David Hilsee" <da*************@yahoo.com> wrote in message
news:1f********************@comcast.com...
"Act" <ot***@hash.com> wrote in message
news:Q6*********************@bgtnsc04-news.ops.worldnet.att.net...
Why is it suggested to not define data members as "protected"?
Some suggest that, some don't. I generally avoid protected data members,
but some people don't mind. For instance, the answers in the FAQ
(http://www.parashift.com/c++-faq-lite/) under "Inheritance - basics",
questions 8 and 9 lean towards protected data.


"Lean"? hehe
I must admit that the
paragraph deriding "purists" is a bit, er, melodramatic.

--
David Hilsee


My take on this is that whenever you use the keyword "protected" you are
expecting your client to derive from the class. In such a case I don't see
why protected data is any better than public data -- either way you are
giving your client full access to your implementation details. The FAQ makes
a big distinction between cases where you expect the client to be "on your
team" or not. Even if I could be sure my client is on my team I don't see
how that makes bad software design practices suddenly desirable. Would you
use public data if you thought your client was on your team? I hope not.

The FAQ also mentions the dubious practice of replacing protected data with
protected get/set methods. I agree, but I don't think public get/set methods
are so hot either.

--
Cy
http://home.rochester.rr.com/cyhome/
Jul 22 '05 #8

P: n/a
* Cy Edmunds:
"David Hilsee" <da*************@yahoo.com> wrote in message
news:1f********************@comcast.com...
"Act" <ot***@hash.com> wrote in message
news:Q6*********************@bgtnsc04-news.ops.worldnet.att.net...
Why is it suggested to not define data members as "protected"?
Some suggest that, some don't. I generally avoid protected data members,
but some people don't mind. For instance, the answers in the FAQ
(http://www.parashift.com/c++-faq-lite/) under "Inheritance - basics",
questions 8 and 9 lean towards protected data.


"Lean"? hehe
I must admit that the
paragraph deriding "purists" is a bit, er, melodramatic.

--
David Hilsee


My take on this is that whenever you use the keyword "protected" you are
expecting your client to derive from the class. In such a case I don't see
why protected data is any better than public data -- either way you are
giving your client full access to your implementation details.


A derived class (on the one hand) and so-called client code (on the other
hand) are two different kinds of client.

A derived class is a fully trusted client: you're giving it access to your
innards, and if it screws up then you (or it) is dead anyway.

So-called client code is a non-trusted client: you're doing your utmost to
ensure that nothing client code can do while _adhering_ to the stated
contracts can screw up anything. But on the gripping hand it's futile to
try to protect against intentional misdeeds. Anyone can reinterpret_cast,
and/or make their own modified class declaration, or whatever, so the
protection levels should be assigned with that in mind: you're not protecting
agains intentional hacking and misdeeds, but against accidental blunders, and
the care you can and must assume in the client depends on the kind of client.
The FAQ makes
a big distinction between cases where you expect the client to be "on your
team" or not.


A good point, but "on your team", if that's the expression the FAQ uses, is
a bit misleading.

It should be more like "part of your body"... ;-)

But these times even that is perhaps not strong enough: a derived class is
a very, Very, VERY intimate & strong relationship.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 22 '05 #9

P: n/a
* John Brown:
Why is it suggested to not define data members as "protected"?


IMO that's too general an advice to be meaningful. From
where did you get this suggestion?


Stroustrup for one (referring to protected data in particular). See section
15.3.1.1 in http://www.research.att.com/~bs/3rd.html


Perhaps you would kindly quote the passage instead of giving a reference
that doesn't contain or give further reference to the passage.

I once had the 3rd edition but now am left with only 1st and 2nd editions.

Anyway it's not our job to do the work in making your argument: DIY.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 22 '05 #10

P: n/a
"Alf P. Steinbach" <al***@start.no> wrote in message
news:41****************@news.individual.net...
<snip>
The FAQ makes
a big distinction between cases where you expect the client to be "on your team" or not.
A good point, but "on your team", if that's the expression the FAQ uses,

is a bit misleading.

It should be more like "part of your body"... ;-)
I'm not sure what you mean by "part of your body". The FAQ was basically
arguing that derived classes tend to be limited in number and maintained by
your team, so a base class change that causes the derived classes to change
will not cause much grief.
But these times even that is perhaps not strong enough: a derived class is
a very, Very, VERY intimate & strong relationship.


A derived class's relationship with its base is only as intimate as the base
allows it to be. For example, a class that derives from std::vector has no
stronger relationship than any other client. If the base exposes a lot in
its "protected interface", then yes, the derived class may have to be
updated if the base class changes. However, this is not required by any
means.

--
David Hilsee
Jul 22 '05 #11

P: n/a
* David Hilsee:
"Alf P. Steinbach" <al***@start.no> wrote in message
news:41****************@news.individual.net...
<snip>
The FAQ makes
a big distinction between cases where you expect the client to be "on your team" or not.
A good point, but "on your team", if that's the expression the FAQ uses,

is
a bit misleading.

It should be more like "part of your body"... ;-)


I'm not sure what you mean by "part of your body". The FAQ was basically
arguing that derived classes tend to be limited in number and maintained by
your team, so a base class change that causes the derived classes to change
will not cause much grief.
But these times even that is perhaps not strong enough: a derived class is
a very, Very, VERY intimate & strong relationship.


A derived class's relationship with its base is only as intimate as the base
allows it to be.


True but irrelevant: when you design for inheritance you're aiming for the
very Very VERY intimate relationship, not the armored warfare relationship;
and there's basically nothing in-between the these points, for any brink in
the armor gives the first kind automatically.

For example, a class that derives from std::vector has no stronger
relationship than any other client.
I don't care to check that for accuracy, but again: even if true it's
irrelevant. You might want to check out std::list for a counter-example.

If the base exposes a lot in
its "protected interface", then yes, the derived class may have to be
updated if the base class changes.
Replace "a lot" with "anything", and tack onto the end, "in the protected
interface"... ;-)

In other words, that statement is misleading in two ways.

A more general & correct statement: if a base class is changed, then any
derived class may have to be updated. And the consequence is that the
cost of design, the cost of updates, the cost of deriving and using, the
cost of (in)efficiency, and so on, must be balanced. That's an engineering
decision requiring sound judgement: it should not, IMO, be made using
cookbook recipe rules like "don't use protected for data members".

However, this is not required by any means.


Right, but see above.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 22 '05 #12

P: n/a
"Alf P. Steinbach" <al***@start.no> wrote in message
news:41****************@news.individual.net...
* John Brown:
> Why is it suggested to not define data members as "protected"?

IMO that's too general an advice to be meaningful. From
where did you get this suggestion?


Stroustrup for one (referring to protected data in particular). See section 15.3.1.1 in http://www.research.att.com/~bs/3rd.html


Perhaps you would kindly quote the passage instead of giving a reference
that doesn't contain or give further reference to the passage.


It's about 4 paragraphs long. I don't want to quote the whole thing, but in
my copy of special edition, it says things like "declaring data members
protected is usually a design error", "protected data becomes a software
maintenance problem", and "none of these objections are significant for
protected member functions; protected is a fine way of specifying operations
for use in derived classes".

--
David Hilsee
Jul 22 '05 #13

P: n/a
"Alf P. Steinbach" <al***@start.no> wrote in message
news:41****************@news.individual.net...
* David Hilsee:
"Alf P. Steinbach" <al***@start.no> wrote in message
news:41****************@news.individual.net...
<snip>
> The FAQ makes
> a big distinction between cases where you expect the client to be "on
your
> team" or not.

A good point, but "on your team", if that's the expression the FAQ
uses, is
a bit misleading.

It should be more like "part of your body"... ;-)
I'm not sure what you mean by "part of your body". The FAQ was basically arguing that derived classes tend to be limited in number and maintained by your team, so a base class change that causes the derived classes to change will not cause much grief.
But these times even that is perhaps not strong enough: a derived
class is a very, Very, VERY intimate & strong relationship.


A derived class's relationship with its base is only as intimate as the

base allows it to be.


True but irrelevant: when you design for inheritance you're aiming for the
very Very VERY intimate relationship, not the armored warfare

relationship; and there's basically nothing in-between the these points, for any brink in the armor gives the first kind automatically.
Well, _you_ may aim for a very intimate relationship. I was pointing out
that an intimate relationship can be avoided. IMHO, the usage of an extra
exposed detail or two in the protected interface does not automatically
constitute a "very very VERY intimate relationship". It's more intimate
than others who are restricted to the public interface, that's for sure.
I'd argue that there is certainly an area in between "armored warfare" and
"extremely intimate".
For example, a class that derives from std::vector has no stronger
relationship than any other client.


I don't care to check that for accuracy, but again: even if true it's
irrelevant. You might want to check out std::list for a counter-example.


How is std::list a counterexample? It has no standard protected members.
If the base exposes a lot in
its "protected interface", then yes, the derived class may have to be
updated if the base class changes.


Replace "a lot" with "anything", and tack onto the end, "in the protected
interface"... ;-)

In other words, that statement is misleading in two ways.

A more general & correct statement: if a base class is changed, then any
derived class may have to be updated. And the consequence is that the
cost of design, the cost of updates, the cost of deriving and using, the
cost of (in)efficiency, and so on, must be balanced. That's an

engineering decision requiring sound judgement: it should not, IMO, be made using
cookbook recipe rules like "don't use protected for data members".


Oh, sure, the FAQ argues this too: one size does not fit all.

--
David Hilsee
Jul 22 '05 #14

P: n/a
* David Hilsee:
"Alf P. Steinbach" <al***@start.no> wrote in message
news:41****************@news.individual.net...
* David Hilsee:
"Alf P. Steinbach" <al***@start.no> wrote in message
news:41****************@news.individual.net...
<snip>
> > The FAQ makes
> > a big distinction between cases where you expect the client to be "on your
> > team" or not.
>
> A good point, but "on your team", if that's the expression the FAQ uses, is
> a bit misleading.
>
> It should be more like "part of your body"... ;-)

I'm not sure what you mean by "part of your body". The FAQ was basically arguing that derived classes tend to be limited in number and maintained by your team, so a base class change that causes the derived classes to change will not cause much grief.

> But these times even that is perhaps not strong enough: a derived class is > a very, Very, VERY intimate & strong relationship.

A derived class's relationship with its base is only as intimate as the base allows it to be.


True but irrelevant: when you design for inheritance you're aiming for the
very Very VERY intimate relationship, not the armored warfare

relationship;
and there's basically nothing in-between the these points, for any brink

in
the armor gives the first kind automatically.


Well, _you_ may aim for a very intimate relationship. I was pointing out
that an intimate relationship can be avoided. IMHO, the usage of an extra
exposed detail or two in the protected interface does not automatically
constitute a "very very VERY intimate relationship". It's more intimate
than others who are restricted to the public interface, that's for sure.
I'd argue that there is certainly an area in between "armored warfare" and
"extremely intimate".


Okay, we'll have to agree to disagree here. Except that I agree that the
I-word relationship can be avoided -- but IMO at very high cost. So!

For example, a class that derives from std::vector has no stronger
relationship than any other client.


I don't care to check that for accuracy, but again: even if true it's
irrelevant. You might want to check out std::list for a counter-example.


How is std::list a counterexample? It has no standard protected members.


Bugger this keyboard. It doesn't write what I mean. Three examples of
standard containers with protected data members are std::queue, std::stack
and std::priority_queue (this time I checked it out, hope this helps).

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 22 '05 #15

P: n/a
"Alf P. Steinbach" <al***@start.no> wrote in message
news:41****************@news.individual.net...
<snip>
> For example, a class that derives from std::vector has no stronger
> relationship than any other client.

I don't care to check that for accuracy, but again: even if true it's
irrelevant. You might want to check out std::list for a
counter-example.
How is std::list a counterexample? It has no standard protected
members.
Bugger this keyboard. It doesn't write what I mean. Three examples of
standard containers with protected data members are std::queue, std::stack
and std::priority_queue (this time I checked it out, hope this helps).


I realize that there exist classes within the standard library that expose
protected members. I wasn't trying to say that any inheritance relationship
established with a standard class is as intimate as one with any other
standard class. I was just pointing out that a class can limit the
interface it exposes to the derived class so much that its relationship is
the same as any other client, if that is what the programmer desires. Of
course, I picked std::vector as an extreme case because it's not really
designed for inheritance at all.

--
David Hilsee
Jul 22 '05 #16

P: n/a
[snip]

My take on this is that whenever you use the keyword "protected" you are
expecting your client to derive from the class. In such a case I don't see why protected data is any better than public data -- either way you are
giving your client full access to your implementation details.
A derived class (on the one hand) and so-called client code (on the other
hand) are two different kinds of client.

A derived class is a fully trusted client: you're giving it access to your
innards, and if it screws up then you (or it) is dead anyway.


A "trusted client"? That's where we disagree. Sure, over the next few months
you and your teammates will probably all be there and understandings and
agreements you have in place will work OK. But as time goes by people come
and go. If your code is to still be maintainable with a new set of players
my advice is: don't trust anybody!

Obviously, if there are pressing issues of performance or whatever that
demand protected data you do what you gotta do. Otherwise, IMHO it's just
plain sloppy programming.

[snip]

But these times even that is perhaps not strong enough: a derived class is
a very, Very, VERY intimate & strong relationship.


I see no reason why it need be any more intimate than a public interface.

--
Cy
http://home.rochester.rr.com/cyhome/
Jul 22 '05 #17

P: n/a

"Alf P. Steinbach" <al***@start.no> wrote in message
news:41****************@news.individual.net...
... But on the gripping hand ...


Cool! You know, I've never heard anyone else ever mention that term before.
I thought that maybe I was the only one to ever read that book! :-)

-Howard


Jul 22 '05 #18

P: n/a

"Cy Edmunds" <ce******@spamless.rochester.rr.com> wrote in message
news:Ln_7d.264334>
The FAQ also mentions the dubious practice of replacing protected data with protected get/set methods. I agree, but I don't think public get/set methods are so hot either.


You agree with a "dubious practice"? That's a strange thing to say... (Or
did you mean you agree that it's a dubious practice? If so, why?)

In any case, you either have to have get/set methods, or you have to expose
the data itself, right? I'm confused which it is that you prefer...?

For me, I tend to use public data for POD structs (e.g., something simple
like a three-d vector with .x, .y and .z members), but I prefer private data
for my more complex classes. However, I do use protected data in some
instances, because I'm generally writing all the classes involved, base and
derived, and it's simply quicker to leave the data as protected and directly
access the members instead of writing a bunch of getters/setters. (There
are also performance issues involved in a few cases, but most of those
involve me deriving from a third-party class that's already made the design
decisions for me.)

As for the visibility of the get/set methods, whether they're protected or
public really depends upon whether I want external code to read or write to
those (perhaps with some kind of checks/asserts/side-effects, etc.), or if
only the derived classes need to read and/or modify those values. If only
derived classes need to know about these "details", the protected
gettters/setters make sense, right? But if they're required information for
the world in general (like the Name of a Person), then surely public
getters/setters are *required*! I mean, if the data itself isn't public,
then what other method of access is there?

In summary, my take on this is that, well, it all depends! No hard-and-fast
rule is likely to apply to all the needs of all the programmers all the
time. We're paid (well, in general), to make intelligent decisions, and we
ought to be able to justify a given decision by thinking it through in the
first place. So if your boss asks "why is this data private instead of
protected", you shouldn't be answering "because protected data is bad", but
rather you should explain why you made the decision in that particular case.

-Howard

"Rule #1: There are exceptions to every rule."

Jul 22 '05 #19

P: n/a
"Howard" <al*****@hotmail.com> wrote in message
news:Oa*********************@bgtnsc05-news.ops.worldnet.att.net...

"Cy Edmunds" <ce******@spamless.rochester.rr.com> wrote in message
news:Ln_7d.264334>
The FAQ also mentions the dubious practice of replacing protected data with
protected get/set methods. I agree, but I don't think public get/set

methods
are so hot either.


You agree with a "dubious practice"? That's a strange thing to say...

(Or did you mean you agree that it's a dubious practice? If so, why?)
I agree that replacing protected data with get/set methods is a dubious
practice.

In any case, you either have to have get/set methods, or you have to expose the data itself, right? I'm confused which it is that you prefer...?
Certainly not! Whatever gave you that idea? If you are programming in the
problem domain instead of just making what BS calls a "bucket of bits" you
would rarely use get/set methods. I often use inspector functions which
*may* correspond to private data items (or I may Google for the return
value -- none of your business!), but I almost always find some other way to
manipulate the object's abstract state than to use a "set" function. In many
simple cases the constructor is all that is needed. In more complex
situations I find the classic idea of thinking of methods as messages quite
helpful.

The problem with excessive use of get/set is that it makes the interface a
thinly disguised C struct.

For me, I tend to use public data for POD structs (e.g., something simple
like a three-d vector with .x, .y and .z members), but I prefer private data for my more complex classes. However, I do use protected data in some
instances, because I'm generally writing all the classes involved, base and derived, and it's simply quicker to leave the data as protected and directly access the members instead of writing a bunch of getters/setters. (There
are also performance issues involved in a few cases, but most of those
involve me deriving from a third-party class that's already made the design decisions for me.)

As for the visibility of the get/set methods, whether they're protected or
public really depends upon whether I want external code to read or write to those (perhaps with some kind of checks/asserts/side-effects, etc.), or if
only the derived classes need to read and/or modify those values. If only
derived classes need to know about these "details", the protected
gettters/setters make sense, right? But if they're required information for the world in general (like the Name of a Person), then surely public
getters/setters are *required*! I mean, if the data itself isn't public,
then what other method of access is there?
Again, I'm kind of amazed. All I can say is that I write a lot of classes
and almost never use the get/set paradigm. The whole point of object
oriented programming is to isolate the interface from the implementation,
but if every data item is required to have a get/set pair, who are you
kidding? I mean, why is that a lot better than public data?

In summary, my take on this is that, well, it all depends! No hard-and-fast rule is likely to apply to all the needs of all the programmers all the
time. We're paid (well, in general), to make intelligent decisions, and we ought to be able to justify a given decision by thinking it through in the
first place. So if your boss asks "why is this data private instead of
protected", you shouldn't be answering "because protected data is bad", but rather you should explain why you made the decision in that particular case.

I agree that it pays to be flexible but I also think it is a good idea to
adhere to good design practices unless there is some pressing reason not to.
So if my boss asked why this data is private instead of protected, I would
ask her what there is about this situation which might motivate me to adopt
a non-standard design practice.

-Howard

"Rule #1: There are exceptions to every rule."


--
Cy
http://home.rochester.rr.com/cyhome/
Jul 22 '05 #20

P: n/a
* Cy Edmunds:
[snip]

My take on this is that whenever you use the keyword "protected" you are
expecting your client to derive from the class. In such a case I don't see why protected data is any better than public data -- either way you are
giving your client full access to your implementation details.
A derived class (on the one hand) and so-called client code (on the other
hand) are two different kinds of client.

A derived class is a fully trusted client: you're giving it access to your
innards, and if it screws up then you (or it) is dead anyway.


A "trusted client"? That's where we disagree. Sure, over the next few months
you and your teammates will probably all be there and understandings and
agreements you have in place will work OK. But as time goes by people come
and go


Consider that you will perhaps not ever know who is deriving from your
class.

Consider that you're writing library code.

The trust relationship has nothing to do with project teams.
If your code is to still be maintainable with a new set of players
my advice is: don't trust anybody!


That's a bit paranoid now, isn't it? I think the code should be maintable
with a any set of players. I don't think one should need to know them.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 22 '05 #21

P: n/a
>The whole point of object
oriented programming is to isolate the interface from the implementation,
but if every data item is required to have a get/set pair, who are you
kidding? I mean, why is that a lot better than public data?


class Point
{
public:

Point(int x,int y);

int GetX() const;
int GetY() const;

void SetX();
void SetY();

private:

int x,y;
};

This class separates its interface from its implementation. I can change how
and where I store the x and y members without affecting how clients read and
write those members.

However, it also has getters and setters corresponding to every data item.

Would you consider this dubious?

A number of years ago in this forum the topic of getters and setters was
discussed and a popular author used the term "visible state." If a particular
data item is part of the "visible state" of an object than it may be perfectly
acceptable to have a getter and or a setter so long as those functions are
written in ways that don't create implementation dependencies (typically
returning by address.)

Regards,
BFS
Jul 22 '05 #22

P: n/a
"DaKoadMunky" <da*********@aol.com> wrote in message
news:20***************************@mb-m14.aol.com...
The whole point of object
oriented programming is to isolate the interface from the implementation,
but if every data item is required to have a get/set pair, who are you
kidding? I mean, why is that a lot better than public data?
class Point
{
public:

Point(int x,int y);

int GetX() const;
int GetY() const;

void SetX();
void SetY();


ITYM void SetX(int); and void SetY(int);

private:

int x,y;
};

This class separates its interface from its implementation.
A little.
I can change how
and where I store the x and y members without affecting how clients read and write those members.
OK, I'm game. Show me your alternate implementation.

However, it also has getters and setters corresponding to every data item.

Would you consider this dubious?
I have written classes pretty much like this one but I didn't include the
set functions. After all, you can always change the state with the
constructor:

Point p1(2, 3);
....
p1 = Point(3, p1.GetY());

A good optimizing compiler should get this right, and the abstraction of a
Point as a pair of numbers (rather than just two numbers) is emphasized.
Plus without the set functions I can use a simpler notation:

class Point
{

private:
int m_x;
int m_y;
public:
Point(int i_x, int i_y) : m_x(i_x), m_y(i_y) {}
int x() const {return m_x;}
int y() const {return m_y;}
};

making the example above

p1 = Point(3, p1.x());

None of this is a big deal, but it does show that it is not usually
necessary to automatically include get/set pairs for every data item.

A number of years ago in this forum the topic of getters and setters was
discussed and a popular author used the term "visible state." If a particular data item is part of the "visible state" of an object than it may be perfectly acceptable to have a getter and or a setter so long as those functions are
written in ways that don't create implementation dependencies (typically
returning by address.)
Yeah, returning an address or a reference would really clobber
encapsulation.

Regards,
BFS


--
Cy
http://home.rochester.rr.com/cyhome/
Jul 22 '05 #23

P: n/a
"Alf P. Steinbach" <al***@start.no> wrote in message
news:41****************@news.individual.net...
* Cy Edmunds:
[snip]
>
> My take on this is that whenever you use the keyword "protected" you are > expecting your client to derive from the class. In such a case I don't
see
> why protected data is any better than public data -- either way you
are > giving your client full access to your implementation details.

A derived class (on the one hand) and so-called client code (on the other hand) are two different kinds of client.

A derived class is a fully trusted client: you're giving it access to your innards, and if it screws up then you (or it) is dead anyway.


A "trusted client"? That's where we disagree. Sure, over the next few

months you and your teammates will probably all be there and understandings and
agreements you have in place will work OK. But as time goes by people come and go


Consider that you will perhaps not ever know who is deriving from your
class.

Consider that you're writing library code.

The trust relationship has nothing to do with project teams.


Hm. I thought this was *my* argument. I guess we agree after all.
If your code is to still be maintainable with a new set of players
my advice is: don't trust anybody!


That's a bit paranoid now, isn't it? I think the code should be maintable
with a any set of players. I don't think one should need to know them.


Exactly. So why did you say:

"A derived class (on the one hand) and so-called client code (on the other
hand) are two different kinds of client."

Since you "don't think one should need to know them" you have no basis for
considering them "different kinds of clients". Right?

Let summarize my position. The same basic information hiding techniques are
available to the C++ programmer for public and protected sections of the
class. These techniques have the effect of increasing maintainability, which
as I'm sure we agree, is highly desirable. As you say, "you will perhaps not
ever know who is deriving from your class". Hence my claim that failure to
apply these techniques is a bad idea in either the protected section or the
public section.

--
Cy
http://home.rochester.rr.com/cyhome/
Jul 22 '05 #24

P: n/a
* Cy Edmunds:

The trust relationship has nothing to do with project teams.
Hm. I thought this was *my* argument. I guess we agree after all.


Heh.

If your code is to still be maintainable with a new set of players
my advice is: don't trust anybody!


That's a bit paranoid now, isn't it? I think the code should be maintable
with a any set of players. I don't think one should need to know them.


Exactly. So why did you say:

"A derived class (on the one hand) and so-called client code (on the other
hand) are two different kinds of client."

Since you "don't think one should need to know them" you have no basis for
considering them "different kinds of clients". Right?


Nope. When someone decides to derive from your class they require more access
to things, paying for that in part by taking on more responsibilities. They
might do so without actually taking on the associated responsibilities. But
that's then their problem, not yours. When they decide to reinterpret_cast a
pointer to an object of your class they require even more access, taking on
even more responsibilities (which again they could fail to actually do)...

Your responsibilities & support for the different usage scenarios are
correspondingly different.

For the case of ordinary "external" usage: protect the client. For the case
of derivation: support what derivation would naturally be used for that is in
addition to what could be achieved by "external" usage, while protecting the
client to the degree that is practical without unduly restricting the client.
For the case of reinterpret_cast and such: no responsibilities as class
designer, except in very-high-security scenarios (where you might consider
encryption of member data, access-restricted OS memory, and such).

Let summarize my position. The same basic information hiding techniques are
available to the C++ programmer for public and protected sections of the
class. These techniques have the effect of increasing maintainability, which
as I'm sure we agree, is highly desirable. As you say, "you will perhaps not
ever know who is deriving from your class". Hence my claim that failure to
apply these techniques is a bad idea in either the protected section or the
public section.


I would agree with a literal interpretation of that. However, also consider
failure to _not_ apply data/functionality hiding, i.e. failure to expose to
derived classes. Since MFC is my favorite repository of bad-design examples
(happily it's been years since last I had to use it...), one infamous case was
the print preview feature, where the only way you could override
functionality, access data and so on -- I forget exactly what, and mention
that lapse of memory because some few things actually were supported -- was
to copy the MFC source code and roll your own version...

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 22 '05 #25

P: n/a
>> This class separates its interface from its implementation.

A little.
A little?

I would say completely.

Clients are dependent upon an interface for getting and setting the x and y
coordinates and the interface signature does not allow clients to become
dependent upon implementation details.

The typical objection I have been exposed to with my example class or classes
like it is the following...

"Well, you are storing member y as an int and your accessor GetY() returns an
int! Your function is just a public data member in disguise!"

If my accessor returned by reference I would agree.

However, my accessor returns by value.

It is just a happy coincidence that the type I return is the type I store.

If for some reason I decide to change how and/or where x and y are stored I can
do so knowing that clients will not need to be rewritten (so long as I am not
changing the meaning of x and y with respect to their conceptual type, which in
this case is int.)
OK, I'm game. Show me your alternate implementation.
I wish I had a better example. I can't think of any reason why I would really
need an implementation other than the one that I originally gave.

The point (no pun intended...honest) is that if I want to change it (maybe to
use dynamically allocated ints, maybe to use an std::pair<int,int>, maybe to
store x and y in a textual representation, maybe to write to a file) that I can
do so without forcing clients to be rewritten because clients are dependent
only upon the interface.

Maybe the Point class is not the best way to illustrate it because it is hard
to imagine any useful alternate implementation.
None of this is a big deal,
The fate of the free world depends upon it :)
but it does show that it is not usually
necessary to automatically include get/set pairs for every data item


Agreed. I would never automatically include getters/setters for every data
item. Every data item needs to be analyzed and a decision made as to whether
or not that data item is part of the visible state of the object. If it is
visible is it visible for reading, writing or both? Then the getter/setter
needs to be written in a way that does not allow implementation details to leak
out.

BFS

Jul 22 '05 #26

P: n/a

"Cy Edmunds" <ce******@spamless.rochester.rr.com> wrote in message
news:KI********************@twister.nyroc.rr.com.. .
"DaKoadMunky" <da*********@aol.com> wrote in message
news:20***************************@mb-m14.aol.com...
The whole point of object
oriented programming is to isolate the interface from the implementation,but if every data item is required to have a get/set pair, who are you
kidding? I mean, why is that a lot better than public data?

I make no claim that every data item requires a get/set pair. Only data
items whose value needs to be known by a client (such as Point.x and
Point.y) require exposure at all. Making them public is fine, if there are
no internal state requirements on those values that a client might
accidently break (note "accidently", not "maliciously"). But if there *are*
strict internal requirements, such as range-checking or side effects that
need to occur when setting, then a setter is a god way to accomplish that.

BTW, your idea of a constructor to manipulate state is, in my opinion, not
very realistic, except perhaps for POD structs (where I'd be likely to use
public data anyway). Especially when using RAII techniques! There may be a
whole slew of activity going on behind the scene, allocating resources you
shouldn't need to know about as a client. It might be quite expensive to
allocate a whole new object, and in some cases may not even be possible
(esp. if a resource allows only single-user access at one time).

class Point
{
public:

Point(int x,int y);

int GetX() const;
int GetY() const;

void SetX();
void SetY();
ITYM void SetX(int); and void SetY(int);

private:

int x,y;
};

This class separates its interface from its implementation.


A little.
I can change how
and where I store the x and y members without affecting how clients read

and
write those members.


OK, I'm game. Show me your alternate implementation.


The Point example doesn't lend itself well to an alternate implementation.
That kind of struct is usually just POD, with public data. But there are
certainly many cases where what appears to be a simple data member may in
fact have some dependencies on other data, may be calculated, may have side
effects when changing, etc. These are cases where getters and/or setters
may come into play. It should be obvious of course that these facts
themselves would indicate to you as a designer whether a getter and/or
setter is needed or not.

In practice, if I'm writing a POD struct, I rarely have any methods at all.
Perhaps a constructor, and an operator or two. But for most of my classes,
everything goes into private data, until I find that there are (or one day
may be) clients that need access. If the clients are derived classes, I
then consider whether to move the data to protected, or to put in a
protected getter and/or setter, as the situation calls for. If the clients
are external, the same considerations need to be made, only with respect to
public visibility.

However, it also has getters and setters corresponding to every data item.
Would you consider this dubious?


I have written classes pretty much like this one but I didn't include the
set functions. After all, you can always change the state with the
constructor:

Point p1(2, 3);
...
p1 = Point(3, p1.GetY());

A good optimizing compiler should get this right, and the abstraction of a
Point as a pair of numbers (rather than just two numbers) is emphasized.
Plus without the set functions I can use a simpler notation:

class Point
{

private:
int m_x;
int m_y;
public:
Point(int i_x, int i_y) : m_x(i_x), m_y(i_y) {}
int x() const {return m_x;}
int y() const {return m_y;}
};

making the example above

p1 = Point(3, p1.x());

None of this is a big deal, but it does show that it is not usually
necessary to automatically include get/set pairs for every data item.


I agree absolutely. The current and future requirements of the system
should determine the design, not some hard-and-fast rules.

-Howard

A number of years ago in this forum the topic of getters and setters was
discussed and a popular author used the term "visible state." If a

particular
data item is part of the "visible state" of an object than it may be

perfectly
acceptable to have a getter and or a setter so long as those functions are written in ways that don't create implementation dependencies (typically
returning by address.)


Yeah, returning an address or a reference would really clobber
encapsulation.

Regards,
BFS


--
Cy
http://home.rochester.rr.com/cyhome/

Jul 22 '05 #27

P: n/a

"Howard" <al*****@hotmail.com> wrote in message
news:3%x8d.491186$OB3.34477@bgtnsc05-

After some more reading, looking at my own code, and seeing some of the
responses here, I'm going to "revise and extend" my remarks a little. I
agree with Mr. Steinbach one one key point, and that is that a derived class
is not really a "client" of a base class at all. At least when using public
inheritance, a derived class, by definition if you will, IS A base class.
Therefore, anything that the base class can do with its members, the derived
class ought also be able to do, without restriction.

Looking at my own class hierarchies, where I have a class that is truly
a client of a second class, invariably the second class is either external
to the first one (with a pointer or reference to the second passed as a
paremeter or stored as a member of the first), or the second class is
contained within the first class as a member itself. This is true "client"
behavior, where one class is asking another to maintain data and perform
tasks for it.

Wherever I have derived classes, it is because the derived class is
simply a specialized or enhanced version of the base class. It is not
asking the base class to do some of its tasks, and doing the rest itself
(although it may seem that way - from a source code point of view - in the
fact that some functions need not be overridden when the base class actions
are sufficient). Rather, it can be thought of as a special case of the base
class itself (such as a MusicEffect class as opposed to just an Effect
class). In that sense, all the actions that take place in what are (in
source code) the base class' member functions, are IN FACT taking place in
the derived object itself, except that behind the scenes there is an
indirection through the vtable (or whatever) to the base class' function
address space. The derived class does not call the base class...the base
class code is executed because the derived class IS A base class.

Given this, I see no reason why making data protected would be wrong, in
cases where the class may be derived from. Making a protected getter or
setter would, in my (updated) opinion, not make much sense for the purpose
of data hiding, because you don't hide data from YOURSELF! I would still
use a getter/setter for cases where the underlying data requires
manipulation or calculation, or creates side-effects when modified, but in
those cases I'd use the getter/setter even WITHIN THE BASE CLASS.
(Otherwise, I'd be requiring myself to write duplicate code everywhere I
read or wrote a member data value.)

Regarding the "don't trust anybody" thought, it is not the
responsibility of the writer of a base class to maintain integrity of that
class if the writer of a derived class desires to write code that changes
the expected internal state of an object of that class. Remember, an
instance of a class is not a class. It's an object, and if someone wants to
write a class whose instances don't work properly, the fact that it is
derived from some base class you wrote is totally irrelevant. Protecting
the state of an instance of the base class from external clients is fine,
because otherwise instances of your base class itself may not perform as
expected. But protecting it from a derived class' actions makes no sense.
Your base class will still function if some moron screws up his derived
class. And even if you consider that there may be an existing third object
or container that depends upon proper behavior of any base or derived
version of your objects, you're still covered, because it's the new stuff
that moron writes that will break, not your stuff, and it's definitely his
responsibility for him to write correct code, not yours. If you need to
protect your work, and anything that depends on your work as well, then
don't allow joe schmoe to derive from your class in the first place. Make
him contain or call instances of your class. Then your code is safe, even
from morons.

-Howard


Jul 22 '05 #28

P: n/a
"Howard" <al*****@hotmail.com> wrote in message
news:o1*********************@bgtnsc04-news.ops.worldnet.att.net...
[...]
Given this, I see no reason why making data protected would be wrong, in cases where the class may be derived from. Making a protected getter or
setter would, in my (updated) opinion, not make much sense for the purpose
of data hiding, because you don't hide data from YOURSELF! I would still
use a getter/setter for cases where the underlying data requires
manipulation or calculation, or creates side-effects when modified, but in
those cases I'd use the getter/setter even WITHIN THE BASE CLASS.
(Otherwise, I'd be requiring myself to write duplicate code everywhere I
read or wrote a member data value.)
[...]


I think this is getting a bit too philosophical. The derived class is not
the base class. If the base class wants to hide something from the derived
class, it is not hiding anything from itself; it's hiding it from the
derived class. Yes, the derived class derives from the base, and
programmers occasionally use "is a" as slang to describe such a
relationship, but that doesn't mean that the derived class has any right to
depend on the implementation of the base. Information hiding may help later
on if the base class needs to change some of its implementation details,
because the derived classes do not have to be modified if it never depended
on it.

--
David Hilsee
Jul 22 '05 #29

This discussion thread is closed

Replies have been disabled for this discussion.