Solved

do I have to make this public?

Posted on 2000-03-17
8
266 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Suggested Solutions

Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their wa…
Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

751 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