Modern C++ standards/conventions...

Started by
49 comments, last by Leo_E_49 16 years, 2 months ago
Quote:Original post by Iftah
I prepend underscore to local member variables, because it is easy to type "_" and press control-space (auto-complete) than to remember or search or type "this->".


I usually find the reverse easier: this-> automatically calls up auto-completion. Besides, it's quite rare that I need to use a variable without knowing what its name is (during class-writing, my classes have so few variables and are written so quickly that it's difficult to forget them, and during maintenance I have to look at variable documentation anyway).

Quote:Also in some IDEs (the one I use at work...) the member variables don't have different syntax highlighting from other local variables so the underscores help highlight them.


This is true. However, I find that this-> highlights member variables even better than an initial underscore does, and it adds no unnecessary clutter, as in:
Test::Test(int x) : _x(x) // Hey, look, '_x' is a member variable !!!{}Test t;t._x = 20; // Hey, look, '_x' is a member variable !!!


Quote:
  abcd     = 5;  dfg      = 4;  asdgfddf = 7;  ds       = 9; // as opposed to  abcd = 5;  dfg = 4;  asdfgfgf = 7;  ds = 2;


Press the tab key?
Advertisement
Quote:Original post by Iftah
I prepend underscore to local member variables, because it is easy to type "_" and press control-space (auto-complete) than to remember or search or type "this->".


That's a pretty bad style.

Quote:from the c++ standard 17.4.3.1.2 Global Names
17.4.3.1.2 Global names

Certain sets of names and function signatures are always reserved to the implementation:
— Each name that contains a double underscore (__) or begins with an underscore followed by an upper-case letter (2.11) is reserved to the implementation for any use.

— Each name that begins with an underscore is reserved to the implementation for use as a name in the global namespace.


Quote:from Herb Sutter
11. style: Try to avoid names with leading underscores. Yes, I've habitually used them, and yes, popular books like "Design Patterns" (Gamma et al) do use it... but the standard reserves some leading-underscore identifiers for the implementation and the rules are hard enough to remember (for you and for compiler writers!) that you might as well avoid this in new code. (Since I'm no longer allowed to use leading underscores as my "member variable" tag, I'll now use trailing underscores!)




if you think programming is like sex, you probably haven't done much of either.-------------- - capn_midnight
Quote:
Each name that begins with an underscore is reserved to the implementation for use as a name in the global namespace.


Member variables should be fine, unless followed by an uppercase character.
Quote:Original post by ToohrVyk
Press the tab key?
Embedded tabs are evil.

Σnigma
Quote:Original post by Enigma
Quote:Original post by ToohrVyk
Press the tab key?
Embedded tabs are evil.


So you tell your IDE to output spaces instead of tab characters? Unless embedded spaces are evil too...
Quote:Original post by rip-off
Quote:
Each name that begins with an underscore is reserved to the implementation for use as a name in the global namespace.


Member variables should be fine, unless followed by an uppercase character.


It will probably work, but that doesn't make it good style. If you're using the var in a member function, there's no way to tell visually that it's a member var and not a system global.

I'm not arguing that you shouldn't use a convention to specify scope, just don't use this one. If you want to specify scope use "this->" or if that's too long, "m_"

if you think programming is like sex, you probably haven't done much of either.-------------- - capn_midnight
Quote:Original post by Enigma
Quote:Original post by ToohrVyk
Press the tab key?
Embedded tabs are evil.
Which is precisely the reason why most IDEs and many editors have the tab key do something other than insert tab characters. For example, emacs will insert as many spaces as necessary to indent the current line correctly.

Quote:Original post by yoshscout
second about getters/setters:
i really thought they were pointless as hell for the longest time. until i saw this...

*** Source Snippet Removed ***

if we dont have that in place now we would normally remove the name variable and fix all the errors? this is a better standard for this reason. im willing to throw out a far fetched (no im not a satist) idea.... look to java for good standards? =0) (please no flames lol!)


I think you're missing the argument against getters and setters.

It's true that getters and setters are generally better than exposing the member variable directly, as your example demonstrates.

However, there is still a better way, and that's to not expose the variables at all, unless you absolutely have to, and then, only grant the bare minimum of access, and expose it in a manner that makes the fewest possible assumptions about the internal implementation details.

Suppose for example, you had a camera class. You could type something like this:

class camera{public:    float GetFov();    void SetFov(float);    vector2 GetPos();    void SetPos(vector2);    vector2 GetLookat();    void SetLookat(vector2);    uint GetViewportWidth();    uint GetViewportHeight();    void SetViewportDimensions(uint, uint);    ...    // etcprivate:    float fov;    vector2 position;    vector2 lookat;    uint viewportWidth;    uint viewportHeight;};


The problem with this is that the internals of the class are still exposed; sure, you have getters and setters, but they're hiding very little. If you changed your internal representation, you'd quickly find that your getters and setters no longer make a lot of sense. For example, suppose you decided to store it's position and facing as a transformation matrix relative to a parent scenegraph node rather than a world space position and lookat vector. All of a sudden you either end up jumping through all kinds of hoops to try and keep to the interface, or you have to completely change the interface and everything that uses it at the same time.

Any time you find yourself writing a class with a proliferation of getters and setters, take that as a hint that you're probably thinking of a class as a collection of loosely related data items, rather than an actual object that does something.
I really liked this reply by Oluseyi as an argument against getters and setters.
I think Oluseyi's post should be read as a reminder to reflect and use common sense, rather than an argument against accessors.
There really is no valid argument against accessors, only against improper use.
Accessors are no more (and no less) evil than operator overloading, virtual inheritance, arrays, or the using keyword. Every language feature and every construct can be used for good or evil.

Some people add an accessor for every class member because they once heard that accessors are "good OOP", or because they use a class generator wizard which does that automatically, or for whatever reason. Maybe they were taught wrong, or they did not listen, or they are just lazy. However, this does not automatically make accessors bad. There are many good and valid uses.
It is not necessary to expose implementation details when using accessors, either (although most of the time, that's what is done). Often, it doesn't really matter. But if it does, it is easy to hide/abstract the implementation details with a typedef or helper class.
typedef is the one of the best inventions since sliced bread, but I'm sure one can find a way to abuse it, too :)

This topic is closed to new replies.

Advertisement