We help IT Professionals succeed at work.

Check out our new AWS podcast with Certified Expert, Phil Phillips! Listen to "How to Execute a Seamless AWS Migration" on EE or on your favorite podcast platform. Listen Now

x

Access functions, schmaccess functions

nchenkin
nchenkin asked
on
Medium Priority
193 Views
Last Modified: 2010-04-01
OK, I think understand the idea behind encapsulation and access functions. However one thing keeps bothering me: C++ books and FAQ's keep saying to use access functions to hide the implementation. Bruce Eckel, in "Thinking in C++" page 314, for example says "you may learn sometime later that it would be much more useful to represent the state information as a float rather than an int, but because int i is part of public interface you can't change it".

His example has a class with a members:

private:
int i;

public:
int read() const { return i; }
void set( int I ){ i = I; }

What if 'i' did become a float? The read() function now has to return a float and everyone using it has to change their code. The set function has to take a float argument and everyone using it has to change their code, or allow the compiler to do a possibly unintended implicit cast.

The only thing you've hid is the name 'i'. What's so great about that? So, how do you change i from an int to a float without anyone who uses your class knowing it happened?

Thanks,
NC
Comment
Watch Question

Commented:
Unlock this solution and get a sample of our free trial.
(No credit card required)
UNLOCK SOLUTION

Commented:
The example suffers some from being a bit simplistic and suffers a lot from being incomplete.

Now first of all, what this guards against is cases where you change how data is stored within the class, but not how other code interfaces with the class.  So in the previous example, if if you change i from int to float,  the read() function would continue to return an int.  It would have to convert the float to an int and return the int.  This is one change as opposed to making the same change everywhere the number would have been accessed directly if read() hadn't been used.  Similarly, set() would continue to take an int, it would have to convert the int to a float and store the float.  Again, the change would only have to be made in one place not every place the  number is set.
Nietod - that was  a bit "evil" to claim coming when you hadn't written anything!!!

That aside, the problem is this is a really bad (meaning unclear) example.

A better example might be a case where (1) i had to be calculated, (2) stored in another place (e.g. a file or database) or (3) another variable also needed to be updated whenever i was updated.

Here are some cases of the above

(1) I won't give an example for this, but if you figure out that i may change more than one way (e.g. it contains a time, or the result of some calculations), then you can imagine that directly writing to i is more likely to require future changes to calling code than by using access functions.  

A simpler example is :

(2) Suppose i is currently stored in an int variable, but in future might be stored in a database.  If you write a class like this

class someclass
{
 public:
   int i ;
}

then all the calling code will have to change when you decide that i should go into a database, file or whatever.

However if you INITIALLY write the class like this

class someclass
{
private:
int i;

public:
int read() const { return i; }
void set( int I ){ i = I; }
}

When you later decide that i belongs in a file/database rather than in an int variable, you simply remove the int i member function, and rewrite the read and set functions.  The advantage is the calling code would not ever have to change, just the class definition.


(3) Suppose the class also contains a variable called i_squared, which is supposed to contain i*i at all times [I'm sure you can think of a real world example with a more complex calculation that takes a long time].  If this variable is added after the initial definition of the class, all calling code would have to change (to update this variable too) unless you used access functions.


Finally in terms of the book example, he is really talking about a situation similar to my case (2).  He is saying that suppose i was stored internally as a float but presented itself externally to the world as an int.  In this case you wouldn't have to change the calling code, if you used access functions.

Commented:
Now what you probably find unsatisfying about that example/answer is that you are thinking that the read() and set() functions are not "sufficient" if they continue to deal with ints.  They cannot set i to a fractial number and they can only return the integer portion of i.  Thus they can no longer do a complete job.  Not quite right.  If the number expressed by i was always an integer and later the need arose for it to be fractional, then yes, this solution would be insufficient.  But that is a case where the interface to the class has changed.  That is, as far as code outside the class is concerned, the class has changed.  In those sort of cases, you would have to change read() and set() to deal with real numbers and change all the code that uses them.  That is not what this protects against.

This protects against a case where you need to store the number differently inside the class, but the number still has the same "appearance".  That is the number would still be integer in nature, only it would be stored as a floating point number.  Hor example, if the number is used in a long series of floating point calculations, it might be easier and faster to store it in a floating point format.  However, the number would always record an integer value, just in a different format, thus read() and set() could continue to work with ints and do a good job.

make sense?

Commented:
answers,  for questions requiring long answers (it took me 15 minutes on that one) we often lock the question with a short reply so that multiple experts don't work on the same question needlessly.  If you started typing first (and you probably did) and had done the same, I would have seent he question locked and I wouldn't have put in my answer.

However, out answers don't intersect too much, so nchenkin will benefit in any case.

Author

Commented:
nietod,

Thanks. I'm a satisfied customer. Access functions here I come...

NC
Unlock the solution to this question.
Thanks for using Experts Exchange.

Please provide your email to receive a sample view!

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.