Public Data in Private Class or Private Data in Public Class?

D

DaveLessnau

In a book on Data Structures that I'm reading, the authors are
describing various linked lists and trees. In these, they start with
some form of node class. What's driving me crazy is that they define
these such that the data in those node classes is public. As a
specific example (a node they're going to use to build linked lists):

template <typename T>
class node
{
public:
T nodeValue; // data held by the node
node<T> *next; // next node in the list

node() : next(NULL) // default constructor w no init value
{}

node (const T& item, node<T> *nextNode = NULL) :
nodeValue(item), next(nextNode)
{}
};

They then use this node class (with its public data) in the private
areas of their linked list classes. They justify this by saying:
"Making the data in the node objects public does not violate the
object-design principle of information hiding, because end users do not
have access to these low-level objects."

In my ignorance, my feeling is that this is bunk. THEY have access to
those public data items and can mess things up themselves. Plus, if
they change the implementation of node, they'll have to change the code
wherever they use it (standard software engineering stuff). Wouldn't
it be better to make the data (nodeValue and *next) of that node class
private and then provide public setNode and getNode methods? I suppose
there might be some additional overhead in making the setNode and
getNode calls vs just changing the data directly. But, without
measuring the choke points in the completed application, there's no
telling if it makes a difference.

I'm really hoping I'm wrong about this, since it really frosts my
shorts that a couple of Computer Science professors wrote a book with
this kind of programming throughout it.
 
S

Sean Burke

DaveLessnau said:
In a book on Data Structures that I'm reading, the authors are
describing various linked lists and trees. In these, they start with
some form of node class. What's driving me crazy is that they define
these such that the data in those node classes is public. As a
specific example (a node they're going to use to build linked lists):

template <typename T>
class node
{
public:
T nodeValue; // data held by the node
node<T> *next; // next node in the list

node() : next(NULL) // default constructor w no init value
{}

node (const T& item, node<T> *nextNode = NULL) :
nodeValue(item), next(nextNode)
{}
};

They then use this node class (with its public data) in the private
areas of their linked list classes. They justify this by saying:
"Making the data in the node objects public does not violate the
object-design principle of information hiding, because end users do not
have access to these low-level objects."

In my ignorance, my feeling is that this is bunk. THEY have access to
those public data items and can mess things up themselves. Plus, if
they change the implementation of node, they'll have to change the code
wherever they use it (standard software engineering stuff). Wouldn't
it be better to make the data (nodeValue and *next) of that node class
private and then provide public setNode and getNode methods? I suppose
there might be some additional overhead in making the setNode and
getNode calls vs just changing the data directly. But, without
measuring the choke points in the completed application, there's no
telling if it makes a difference.

I'm really hoping I'm wrong about this, since it really frosts my
shorts that a couple of Computer Science professors wrote a book with
this kind of programming throughout it.

Just goes to show that it was an egregious error even to allow
public data members in the first place. Hopefully, future generations
will learn from our tragic errors.

-SEan
 
K

Kristo

DaveLessnau said:
In a book on Data Structures that I'm reading, the authors are
describing various linked lists and trees. In these, they start with
some form of node class. What's driving me crazy is that they define
these such that the data in those node classes is public. As a
specific example (a node they're going to use to build linked lists):

[snip example code]
They then use this node class (with its public data) in the private
areas of their linked list classes. They justify this by saying:
"Making the data in the node objects public does not violate the
object-design principle of information hiding, because end users do
not have access to these low-level objects."

I agree with that justification.
In my ignorance, my feeling is that this is bunk. THEY have access
to those public data items and can mess things up themselves.

That private class is just that, private. You don't use public
accessor functions to modify private data within the class
implementation. If you can't trust yourself to do it right, whom can
you trust?
Plus, if they change the implementation of node, they'll have to
change the code wherever they use it (standard software engineering
stuff). Wouldn't it be better to make the data (nodeValue and *next)
of that node class private and then provide public setNode and
getNode methods? I suppose there might be some additional overhead
in making the setNode and getNode calls vs just changing the data
directly. But, without measuring the choke points in the completed
application, there's no telling if it makes a difference.

One of the fundamental ideas of C++ is that you don't pay for what you
don't use. Such a library would force the function call overhead on
its users. From the users' point of view, it goes like this: "Why
should we pay for the overhead of a function call because the author
didn't trust himself to write the code correctly?" As a library
writer, you can't know in advance what effects your code will have on
performance. Therefore, you should try to make it as tight as
possible.
I'm really hoping I'm wrong about this, since it really frosts my
shorts that a couple of Computer Science professors wrote a book with
this kind of programming throughout it.

While debugging, the function calls you suggest can be useful. You
could include assertions to make sure you aren't violating any class
invariants. However, I think these should be removed for production
code.

Kristo
 
H

Howard

DaveLessnau said:
In a book on Data Structures that I'm reading, the authors are
describing various linked lists and trees. In these, they start with
some form of node class. What's driving me crazy is that they define
these such that the data in those node classes is public. As a
specific example (a node they're going to use to build linked lists):

template <typename T>
class node
{
public:
T nodeValue; // data held by the node
node<T> *next; // next node in the list

node() : next(NULL) // default constructor w no init value
{}

node (const T& item, node<T> *nextNode = NULL) :
nodeValue(item), next(nextNode)
{}
};

They then use this node class (with its public data) in the private
areas of their linked list classes. They justify this by saying:
"Making the data in the node objects public does not violate the
object-design principle of information hiding, because end users do not
have access to these low-level objects."

In my ignorance, my feeling is that this is bunk. THEY have access to
those public data items and can mess things up themselves. Plus, if
they change the implementation of node, they'll have to change the code
wherever they use it (standard software engineering stuff). Wouldn't
it be better to make the data (nodeValue and *next) of that node class
private and then provide public setNode and getNode methods? I suppose
there might be some additional overhead in making the setNode and
getNode calls vs just changing the data directly. But, without
measuring the choke points in the completed application, there's no
telling if it makes a difference.

I'm really hoping I'm wrong about this, since it really frosts my
shorts that a couple of Computer Science professors wrote a book with
this kind of programming throughout it.

Without seeing the class that uses this, I can't comment on whether there is
any way for end-users of the containing class to get at the private data.
But assuming it's private as stated, and not otherwise exposed (via a
GetNode call, for example), then there's no problem regarding information
hiding here. (And no mechanism can prevent you from messing up your own
class' internals, private or otherwise, so that part of your comments is
irrelevant.)


Also, in this example at least, the object is so simple that I don't see
much problem in simply exposing the internals as public. If the object were
more complicated, then I'd agree that its internals should be handled via
function calls. But in this case it's simply a data value and a next
pointer, which isn't as likely to change. If you were to want to add a
previous pointer to the node, for example, then you'd likely be reworking
the linked list code anyway, to make it doubly-linked.

So, in my opinion anyway, this isn't a "bad" thing, at least not in this
case. Show me a case where they're using a more complicated object in this
manner, something with some business logic behind it for example, and I'll
agree with you that it's not such a good idea. But here, it's just too
simple to bother.

-Howard
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,733
Messages
2,569,440
Members
44,829
Latest member
PIXThurman

Latest Threads

Top