Modern C++ standards/conventions...

Started by
49 comments, last by Leo_E_49 16 years, 2 months ago
Quote:Original post by Antheus
int getFoo() const { return foo; }void setFoo(int new_foo) { foo = new_foo; }
is simply pointless. You didn't achieve any encapsulation, you didn't add any new information, and new functionality, you merely increased the code clutter by a factor of 10.

What?!

That, by definition, *IS* encapsulation.

It allows you to change the internal functionality without changing the interface. We strictly enforce it here, and for good reason.

Today, I ended up modifying a few of these. Specifically:

Quote:
void SetLocked(bool flag) { mIsLocked= flag; }void SetBar(foo f) { mFoo=f; }
had been used for months in our code. Your post would say they are unnecessary. But today, they turned in to:
Quote:
void SetBar(foo f) { if(mIsLocked) {   mDelayedFoo = f;   return; } mDelayedFoo = foo::none; mFoo = f; DoSomething(f);}void SetLocked(bool flag){ mIsLocked= flag;  if(flag==false && mDelayedFoo != foo::none) {   SetBar(mDelayedFoo); }}

This is *EXACTLY* the purpose of encapsulation. It reduced what would have been a multi-hour task of finding everywhere that would have modified the value directly (ewww), and dropped it down to a half-hour of figuring it out, fixing it, and testing a simple change inside the well-used interface.
Advertisement
Now I'm cunfused....

both antheus and frob has their point...

@antheus can you elaborate more about get/set method(or what you call getters/setters) being more than accessor method,if possible give some code example on how get/set method become more than accessor method??? what will you do if you what to know an info about a member variable of an object??? so you mean that the member function length() of class string in c++ is useless(or not appropriate)
Encapsulation is only half of the story - simple getters/setters expose implementation details. Here is a relevant discussion on the topic. A good article on hungarian notation and its origins is on there too.
Quote:Original post by frob
Quote:Original post by Antheus
int getFoo() const { return foo; }void setFoo(int new_foo) { foo = new_foo; }
is simply pointless. You didn't achieve any encapsulation, you didn't add any new information, and new functionality, you merely increased the code clutter by a factor of 10.

What?!

That, by definition, *IS* encapsulation.

It allows you to change the internal functionality without changing the interface. We strictly enforce it here, and for good reason.

Today, I ended up modifying a few of these. Specifically:

Quote:
void SetLocked(bool flag) { mIsLocked= flag; }void SetBar(foo f) { mFoo=f; }


The difference is you didn't really have accessors in the first place, just poorly named functions. Is the purpose of SetLocked() to set a variable called 'locked', making it nothing more than a pointless accessor (as the name suggests), or is it's purpose to provide the functionality of locking access to something? Just because the implementation only needs to mark a flag internally doesn't make it an accessor, really SetLocked() would be better called Lock() or something similar depending on what it's doing (and similar argument for SetBar(), whatever it actually does).

Yes it seems minor, but conceptually it's an important distinction. You don't have accessor functions for x,y,z,w on your vector class, right?
"Voilà! In view, a humble vaudevillian veteran, cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valorous visitation of a bygone vexation stands vivified, and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition. The only verdict is vengeance; a vendetta held as a votive, not in vain, for the value and veracity of such shall one day vindicate the vigilant and the virtuous. Verily, this vichyssoise of verbiage veers most verbose, so let me simply add that it's my very good honor to meet you and you may call me V.".....V
So I read that post on getters/setters and it was an informative read. But what if other classes simply need the data? For example a camera class. Would its position/target/up vectors be public? And what about a scene node, surely other classes will need to get their positions and orientations, would their matrices be public aswell?

I see how getters/setters can be reduced (after reading that post). But I am very hesitant to put data that simply needs to be accessed by other classes public. Getters/setters make so much more sense than that (to me).

Am I not thinking about this correctly?
Quote:Original post by c_olin
So I read that post on getters/setters and it was an informative read. But what if other classes simply need the data? For example a camera class. Would its position/target/up vectors be public? And what about a scene node, surely other classes will need to get their positions and orientations, would their matrices be public aswell?


Using getters only is perfectly valid as sometimes internal state needs to be read (how else do you print out a characters stats?). In your case you could provide a getter for the node's transformation matrix but you wouldn't provide a setter (since you don't want someone to be able to set random values in the transformation), you would instead provide functions such as Translate(), Rotate(), etc.
"Voilà! In view, a humble vaudevillian veteran, cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valorous visitation of a bygone vexation stands vivified, and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition. The only verdict is vengeance; a vendetta held as a votive, not in vain, for the value and veracity of such shall one day vindicate the vigilant and the virtuous. Verily, this vichyssoise of verbiage veers most verbose, so let me simply add that it's my very good honor to meet you and you may call me V.".....V
Quote:Original post by c_olin
So I read that post on getters/setters and it was an informative read. But what if other classes simply need the data? For example a camera class. Would its position/target/up vectors be public? And what about a scene node, surely other classes will need to get their positions and orientations, would their matrices be public aswell?

I see how getters/setters can be reduced (after reading that post). But I am very hesitant to put data that simply needs to be accessed by other classes public. Getters/setters make so much more sense than that (to me).

Am I not thinking about this correctly?
It's all about keeping the data, and the methods that operate on that data, in the same class. Providing getters and setters typically seperates the algorithms that use the data from the class that holds it.
The variables usually either should belong in a different class, or the functions operating on them need to belong to the class holding the variables. As with everything though, there are exceptions.
"In order to understand recursion, you must first understand recursion."
My website dedicated to sorting algorithms
Quote:Original post by joanusdmentia
Quote:Original post by c_olin
So I read that post on getters/setters and it was an informative read. But what if other classes simply need the data? For example a camera class. Would its position/target/up vectors be public? And what about a scene node, surely other classes will need to get their positions and orientations, would their matrices be public aswell?


Using getters only is perfectly valid as sometimes internal state needs to be read (how else do you print out a characters stats?). In your case you could provide a getter for the node's transformation matrix but you wouldn't provide a setter (since you don't want someone to be able to set random values in the transformation), you would instead provide functions such as Translate(), Rotate(), etc.


Yeah, I definitely see why a setting would not be a good idea in that case. But what about the camera class? I've already run into places where I need to change the FOV or the target from outside the class. Is it a bad idea to have both a getter and a setter for the FOV or the target vector? Should it be public?

Quote:Original post by c_olin

Yeah, I definitely see why a setting would not be a good idea in that case. But what about the camera class? I've already run into places where I need to change the FOV or the target from outside the class. Is it a bad idea to have both a getter and a setter for the FOV or the target vector? Should it be public?


On the camera you definitely don't want data like FOV etc public because:
1. this will lock you down to a single internal representation of a camera
2. you cant manage stuff like "recalculate view matrix when user want to change FOV automatically" without some encapsulement.

Things like this have to decided on a case-by-case basis. If you have POD type (plain old data, like vector etc) you don't want accessors. If you have something where its a gain to hide the internal representation and you have a feeling it might change in the future (this stuff is all down to experience).

If you are unsure, go with accessor methods. it better than having used public data and suddenly need to hook in some extra logic when that data is changed, but as mentioned above, going the old Java route and making everything public will spread out solutions to particular problems and increase dependencies between classes.





Quote:Original post by c_olin
What about in a similar case that happens to be in a public function rather than a constructor?
void Foo::Bar(int x){  this -> x = x;}

This topic is closed to new replies.

Advertisement