Trailing underscores for member variables in C++

2019-01-22 02:05发布

问题:

I've seen people use a trailing underscore for member variables in classes, for instance in the renowned C++ FAQ Lite.

I think that it's purpose is not to mark variables as members, that's what "m_" is for. It's actual purpose is to make it possible to have an accessor method named like the field, like this:

class Foo {
public:
    bar the_bar() { return the_bar_; }
private:
    bar the_bar_;
}

Having accessors omit the "get_" part is common in the STL and boost, and I'm trying to develop a coding style as close to these as possible, but I can't really see them using the underscore trick. I wasn't able to find an accessor in STL or boost that would just return a private variable.

I have a few questions I'm hoping you will be able to answer:

  1. Where does this convention come from? Smalltalk? Objective-C? Microsoft? I'm wondering.
  2. Would I use the trailing underscore for all private members or just as a workaround in case I want to name a function like a variable?
  3. Can you point me to STL or boost code that demonstrates trailing underscores for member variables?
  4. Does anybody know what Stroustrup's views on the issue are?
  5. Can you point me to further discussion of the issue?

回答1:

In C++,

  1. identifiers starting with an underscore, followed by a capital character
  2. identifiers having two consecutive underscores anywhere
  3. identifiers in the global namespace starting with an underscore

are reserved to the implementation. (More about this can be found here.) Rather than trying to remember these rules, many simply do not use identifiers starting with an underscore. That's why the trailing underscore was invented.

However, C++ itself is old, and builds on 40 years of C (both of which never had a single company behind them), and has a standard library that has "grown" over several decades, rather than brought into being in a single act of creation. This makes for the existence of a lot of differing naming conventions. Trailing underscore for privates (or only for private data) is but one, many use other ones (not few among them arguing that, if you need underscores to tell private members from local variables, your code isn't clear enough).

As for getters/setters - they are an abomination, and a sure sign of "quasi classes", which I hate.



回答2:

I've read The C++ Programming Language and Stroustrup doesn't use any kind of convention for naming members. He never needs to; there is not a single simple accessor/mutator, he has a way of creating very fine object-oriented designs so there's no need to have a method of the same name. He uses structs with public members whenever he needs simple data structures. His methods always seem to be operations. I've also read somewhere that he disencourages the use of names that differ only by one character.



回答3:

I am personally a big fan of this guideline: http://geosoft.no/development/cppstyle.html

It includes omitting the m_ prefix, using an underscore suffix to indicate private member variables and dropping the horrid, annoying-to-type habit of using underscores instead of space, and other, more detailed and specific suggestions, such as naming bools appropriately(isDone instead of just done) and using getVariable() instead of just variable() to name a few.



回答4:

Only speaking for myself... I always use trailing underscore for private data members, regardless if they have accessor functions or not. I don't use m_ mainly because it gets in the way when I mentally spell the variable's name.



回答5:

As a maintenance developer that likes searchability I'm leaning towards m_ as its more searchable. When you, as me, are maintaining big projects with large classes (don't ask) you sometimes wonder: "Hmmm, who mutates state?". A quick search for m_ can give a hint.

I've also been known to use l_ to indicate local variables but the current project doesn't use that so I'm "clean" these days.

I'm no fan of hungarian notation. C++ has a strong type system, I use that instead.



回答6:

I'm guessing that utopia would have been to use a leading underscore - this is quite common in Java and C# for members.

However, for C, leading underscores aren't a good idea, so hence I guess the recommendation by the C++ FAQ Lite to go trailing underscore:

All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use.

All identifiers that begin with an underscore are always reserved for use as identifiers with file scope in both the ordinary and tag name spaces.


(ISO C99 specification, section 7.1.3)



回答7:

As far as I remember, it's not Microsoft that pushed the trailing underscore code style for members.

I have read that Stroustrup is pro the trailing underscore.