Solved

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

Posted on 2000-04-01
16
212 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
ID: 2676134
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
ID: 2676138
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
ID: 2676185
>> 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
ID: 2676188
>> 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
ID: 2676195
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
ID: 2676337
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
ID: 2676373
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
ID: 2676650
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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 1

Expert Comment

by:ntdragon
ID: 2676699
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
ID: 2676711
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
ID: 2676758
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
ID: 2676802
>> 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
ID: 2677451
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
ID: 2677471
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
ID: 2677497
as you wish and i hope we helped you
0
 
LVL 22

Expert Comment

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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
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 video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
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…

920 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

18 Experts available now in Live!

Get 1:1 Help Now