Solved

do I have to make this public?

Posted on 2000-03-17
8
246 Views
Last Modified: 2010-04-02
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"
     5
     6  template<class T>
     7  class List;
     8
     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  };
    21
    22  template<class T>
    23  class List
    24  {
    25  public:
    26          List();                         // Constructor
    27          ~List();                        // Destructor
    28
    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
    34
    35          Node<T>* current;               // Current item pointer
    36
    37  private:
    38          Node<T>* head;
    39          Node<T>* tail;
    40
    41  };
    42  
    43  
    44  #endif // LIST_H
0
Comment
Question by:scottd1978
  • 4
  • 4
8 Comments
 
LVL 1

Accepted Solution

by:
loumf earned 25 total points
ID: 2630305
A better way is to make item private and provide access functions

private:
  T item;

public:
  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.
0
 
LVL 22

Expert Comment

by:nietod
ID: 2630468
>> 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.)  
0
 
LVL 1

Expert Comment

by:loumf
ID: 2636168
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.
0
Gigs: Get Your Project Delivered by an Expert

Select from freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely and get projects done right.

 
LVL 22

Expert Comment

by:nietod
ID: 2637241
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.)  
0
 
LVL 1

Expert Comment

by:loumf
ID: 2637364
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.
0
 
LVL 22

Expert Comment

by:nietod
ID: 2637457
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

Initialize_A_T(someclass.GetX());

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.
0
 
LVL 1

Expert Comment

by:loumf
ID: 2637514
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.
0
 
LVL 22

Expert Comment

by:nietod
ID: 2637525
>> 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.
0

Featured Post

Live: Real-Time Solutions, Start Here

Receive instant 1:1 support from technology experts, using our real-time conversation and whiteboard interface. Your first 5 minutes are always free.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Often, when implementing a feature, you won't know how certain events should be handled at the point where they occur and you'd rather defer to the user of your function or class. For example, a XML parser will extract a tag from the source code, wh…
Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.

805 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question