Solved

What is the right way to implement Item 20 in "Effective C++"?

Posted on 2000-04-01
16
210 Views
Last Modified: 2010-04-10
Item 20 :  Avoid data members in the public interface

Providing read access to private data seems
straight forward. In the example below, I
just prepend P to the data item in the private
section and then use a function to return
the value.

But, what if I want to provide write access?
Scott's recommendation seems to be:
     Set_val( int value ) { Pval = value : } ;

But, this means that instead of val = 5,
I have to write Set_val ( 5 ) ;

Which frankly does not seem like a step in the
right direction.


How would you provide write access to Pval
in the example below?

Thanks,
  Ken


Class A {
  int Pval ;
public:
  int val() { return Pval ; } ;
}
0
Comment
Question by:klopter
  • 5
  • 5
  • 2
  • +2
16 Comments
 
LVL 5

Expert Comment

by:vachooho
Comment Utility
class A
{
  int pVal;
public:
  int Val {return pVal};
}

=============================
class B : public A
{
   friend class C;
}

class C
{
public:
    void FunctionThatCanAccess_A_private_vars(A * pClassA)
{
 B * pClassB = (B*)pClassA;
 pClassB->pVal = -777;
};
}

Not the best way to access protected members but can help if you do not have sources for original code.

Seems this is not the answer to your question...


0
 
LVL 5

Expert Comment

by:vachooho
Comment Utility
the other way is to provide operator=
overload

class A
{
....
operator= (int nValue) {pVal = nValue;};
}

this can help if you have only one protected member function

0
 
LVL 22

Accepted Solution

by:
nietod earned 100 total points
Comment Utility
>> Item 20 :  Avoid data members in the public interface
I assume this is from one of Scott Meyer's book.  

They are great books and many of the points in them must be followed without exceptions, others are simply good suggestions.  Others, somewhere in between.  

Avoiding access to public data members is in-between.  If there are data members whose values are ritical to the safe execution of the class, like say a pointer to something, or a critical of some number of somethings, then it is wise to make this data member private.  This prevents nonmember code from messinpg up this critical member.  And if the member does get messed up, you don't have as much code to search for the culprit.   But some data members may not be so critical.  You might have data members that can freely be changed without disasterious side affects and that will need to be changed by non-member code, like you might have a traffic light class that stores the current color.  It may be reasonable to make that color publci so it can easily be changed and tested.  Now you do need to consider these choices carefully.  If there is a chance that the implimentation may change in regard to a data member, or that work may need to be done whenever the data member is accesssed (like updating other data members when it changes) then you shoudl make it private and provide access functions.  (Because is changes are made the access function is the only code that has to change or if additional work need to be done, the access function can be made to do so.)

If you do decide that a data member needs to be protected and have access functions, then a GetXXX()/SetXXXX() pair of functions is the common choice.  The SetXXXX() function sets the member to the new value and the GetXXXX() function returns the current value.  If the class is changed, these functions can often be changed so that the existing code can continue to use them.  

One alternative is to use a single access function that returns a non-constant reference to the data member, like

int &GetVal() { return PVal; };

This single function can be used to get OR set the data member.  i.e.

Obj.GetVal() = Obj.GetVal() + 12;

Both obtains a value and sets it with the same function.   If the class changes its implimentation, This function can often be changed as well so that existing continues to work.  In the worst case this would usually involve writting a proxy class that is returned by the new form of the function.  The proxy class would then detect the change and update the original class.   Not very pretty.  So this design has questionable values, but it is worth considering.
0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
>> I have to write Set_val ( 5 ) ;
>>
>> Which frankly does not seem like a step in the
>> right direction.
Is there a particular reason you don't like that?  If you are worried about efficiency, you can make the function inline, there is an excelent chance optimizer will end up producing the same code that woudl occur if you simply set the data member.
0
 
LVL 1

Expert Comment

by:ntdragon
Comment Utility
i'm repeating what allready was siad
what you should do is to take Scott's recommendation but instead of Set_Val
write operator=

then you"ll have a function like Set_Val
and you"ll call it by the operator = as you wanted
0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
But what if you have two int data members in a class?  how do you set them both with operator =?  
0
 
LVL 1

Expert Comment

by:jwilcox
Comment Utility
You don't...the get()/set() method is probably the least confusing implementation to shoot for, so I agree with you nietod.
0
 

Author Comment

by:klopter
Comment Utility
My take on all this is that if I want
a variable which can easily (by easy I
mean using the assignment operator =)
by read and written and I don't
expect that variable to be consistent
with other data in the class (or as
nietod says "is not critical ..."), I should
just make that variable public.  

If I decide that a variable needs to
be protected, I should use get_X and set_X
functions.

Overloading = only works for one
variable in the class.  

The upshot is that I am going to
make most variables public because
I am comfortable with that.  Knowing
that I am violating a Scott Myers' law.

Someday, I will revisit this.

Ken
0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 1

Expert Comment

by:ntdragon
Comment Utility
i still don't agree with you
you shouldn't make them public

what problrm do you have with the operator=???

second if you have a variable in public you can use '=' instead of the set_func
nothing will stop you 'cause the variable is public

that is all the idea of the private you can make a variable private and with the operator = you can make it look like it public

when you write class's you should be consistent with other data in c++

about operator = that will update more then one variable you can make
operator=(void*a);
and then you can updata all the class variables
0
 
LVL 1

Expert Comment

by:jwilcox
Comment Utility
As long as everyone and their mother is giving input on this issue, I thought I'd throw in mine. I am a very big fan of hiding data members behind private walls, and then just giving interfaces to modify them. My big reason for this is because I love to alter my data structures, when I think of a better way of doing things, etc. and I like being able to hide those changes from the world, making it alot easier to change data structures.

I also think that operator overloading alot of the time just adds confusion rather than clearing things up...like when I'm operating on my class Pizza, what does + do? Does it increase pizza size, toppings, # of pizzas??

Have a great weekend,
0
 
LVL 1

Expert Comment

by:ntdragon
Comment Utility
as you know you overload operators only if there is a logic in it <a logic that every one can understand not only you>

like in string class you guest what operator + do it somthing that every programer will guest
but it hard to guest what will do operator -
0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
>> I should just make that variable public.  
Yes but only after careful consideration.  This is clearly a violation of encapsulation, which most OOP programmers would consider an undeniable mistake.  On the other hand, this is what we always did before OOP so it can't be that bad.   The answer lies in knowing advantages of enapsulation and employing it wereever there is or even might be an advantage.  Where there is no advantage, its your call.

>> i still don't agree with you
>> you shouldn't make them public
Why?  You can probably give 100s of cases where it would be bad to do so, but can you say for every case?  Not really.

>> that is all the idea of the private you can make a
>> variable private and with the operator = you can
>> make it look like it public
and why is it advantageous to do that?  You haven't restricted access to the data member.   The only case you could make in favor of this is that if the implimentation was changeed so that data member was changed in type or removed or something, then the operator = might be able to still work.  That is a reasonable point, but sometimes it just not worth the trouble for data members you are extremely conifdent of....
0
 
LVL 1

Expert Comment

by:ntdragon
Comment Utility
you see the only thing i want to say is if he want to controll the access to pval it should be private not public
if it public you got full controll allways
0
 

Author Comment

by:klopter
Comment Utility
The upshot is that I know that I am
violating encapsulation by making just about
everything public.  I have decided that
encapsulation is one aspect of C++/OOP
that I am going to ignore for now in favor
of getting my work done.  

My boss is already on my case for spending
too much time learning C++ and not enough
writing code.  

On my next project I will try to focus on encapsulation.  

Thanks,
  Ken
0
 
LVL 1

Expert Comment

by:ntdragon
Comment Utility
as you wish and i hope we helped you
0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
>>  if he want to controll the access to
>> pval it should be private not
>> public
definitely.

klopter, This probably wouldn't help you get things done in the shortrun, but what I did is to write a code pre-processor program that looks at my class definitions and looks for data members that are supposed to have Get/Set functions (it figures this out via comments on the data members). and ths program then writes the Get/Set() functions and inserts them in the code.  its a nice time saver.  Does lots of other things too, like finds the member functions that are defined outside of the class and creates the declarations for them inside the class.  

You may want to consider that for the future.
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
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 be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

762 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

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now