do I have to make this public?

I'm doing a linked list class that holds instances of 7 or 8 classes that I've written.  I want to be able to access these classes methods.  list->item.methodname(); ... is there anyway to do this without declaring my item field public?
     1  #ifndef LIST_H
     2  #define LIST_H
     3  #include <iostream.h>
     4  #include "/home/mud/classes/object/object.cpp"
     6  template<class T>
     7  class List;
     9  template<class T>
    10  class Node
    11  {
    12          friend List<T>;
    13          public:
    14                  // This is declared public because we need to access functions
    15                  // of the item from outside functions and classes.  I wish I
    16                  // knew of a better way to do this.
    17                  T item;                 // This will hold an object of type T
    18          private:
    19                  Node *next;
    20  };
    22  template<class T>
    23  class List
    24  {
    25  public:
    26          List();                         // Constructor
    27          ~List();                        // Destructor
    29          void add(int new_item);         // Add an item to the end of the list
    30          void kill(int x);               // Delete the specified item
    31          void seek(int x);               // Set the current pointer to the specified item
    32          void print();                   // Print the descriptions of all the items
    33                                          // This is only for testing
    35          Node<T>* current;               // Current item pointer
    37  private:
    38          Node<T>* head;
    39          Node<T>* tail;
    41  };
    44  #endif // LIST_H
Who is Participating?
loumfConnect With a Mentor Commented:
A better way is to make item private and provide access functions

  T item;

  T& GetItem() { return item; }
  const T& GetItem() const { return item; }

Try to never expose a member variable, always use access functions.

Other suggestions:
List<T>::add() should take const T& not int

current should be made private and a GetItem function should be added to List

T& GetItem() { return current->GetItem(); }

There is no reason for clients of list to know about Nodes.  This way you have the flexibility to change the way you implement list.
>> Try to never expose a member variable,
>> always use access functions.
That is a little to absolute for my tastes.  There are times when it may make sense to expose data members as public.   You probably don't want to make data members that are important to the class's implimentation public, especially if improper "meddling" with the data member could cause a crash, but there may be no harm to making less critical data members public, especailly if you feel confidant that the design is stable and that the data members will not change (which tends to be rare.)  
How could it possibly be better to use an exposed data member over an inlined access function?  

There is no flexibility in exposing a data member.  Even if you never remove it, there are great benefits to hiding it.

1. I can add more code to the access functions, making them a point of future extension.

2. I can put a break point in the access functions whenever I need to understand more about the run-time behavior (who actually sets or gets an objects members).  If there is no access function, then this is almost impossible.

Not to mention the huge benefits I get if I need to refactor this class.
Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

It doesn't ALWAYS make sense to do, but sometimes it does.  Consider a class that contains a very large C structure, like a windows LOGFONT for example, it may be easier to make the structure public, rather than providing access teach data member in the structure (or one single function for the entire structure, which may be very inefficient.)  
My assumption is that

T& GetX() { return _x; }

is never worse than exposing _x.  That being the case, I don't see any reason to make it public.
That if a good argument--for my point.  

Now what if _x is a large structure and the code using GetX() needs to "fill it in" by passing it to an initialze function.  (Not a far-fetched example, you often see this in initializing the structures defined by the OS or by a 3rd part library.)   So you do


Now what if you change someclass's implimentation so it no longer stores _x as a T.  The code doesn't work anymore, right?  The "traditional" solution is to make GetX return a proxy class that converts to type T and that can "detect the changes made to the T and make the cooresponding changes to the new data that is actually stoed in the someclass object.  Unfortuantely, that doesn't work in this case the Initialize_A_T won't take the proxy class, so the code won't compile.

If you return a non-constant reference to private data member, you might as well make the member public, you've lost the protection offered by private data members.  The data member can be changed freely without "detection" by the class and attempts to change the implimentation of the class may cause existing code to fail.

Also If the class is in a DLL the excess access functions can get costly.
So the access function is no worse than not having it.

In some cases T& GetX() is also bad (the cases you mentioned), but I still don't understand when it is worse than exposing a public member.

The DLL statement at the end is the only argument that is for exposing the member.  I think that if I found through profiling that there was a bottleneck from an access function, then I'd think about exposing the member.

The other case where it might be ok to leave it exposed is in prototype code--as long as you throw it away.

We're starting to get into style which is never going to get resolved.  I think it the long run, if you always make access functions, and optimize when you have a performance problem, you're going to be a lot better off than trying to figure out each time that you have a member variable whether you should expose it.
>> but I still don't understand when it is
>> worse than exposing a public member.
It may cause overhead as it may not be inlined, it causes longer compiles and more source code, it causes larger libraries.  There probalby are other reasons to.  I'm not saying that all data members should be made public, but one that is so loosely controlled as in your example certainly could be.
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.