Naming Patterns

Name the variable is a big issue when you're coding. A good variable name should meet the following requirements

  • Easy to understand what it does
  • Easy to know how to operate it

The naming issues

class Person()
{
public:
  Person(str::string name, unsigned int age, Person* dad, Person* mom)
    : name(name)
    , age(age)
    , dad()
    , mom()
  {
  }

  std::string Name()
  {
    return name;
  }

private:
  std::string name;
  unsigned int age;
  Person* dad;
  Person* mom;
};

name(name) and age(age) will make readers confused.

Using Prefix

One solution for making the variables clearer is to use prefix (discussion about why using prefix). Suppose we use m as the prefix for member variable, then name(name) should be changed to mName(name). Such changing will make the code clearer for the readers.

How about using this

You may argue that you can use this-> to avoid the ambiguous naming problem. Nevertheless, this-> can't be used for static members in some languages(e.g., C++). What's worse is that you no longer can use g++ -Wshadow warnings.

Common prefix

  • a : argument
  • c, k: constant
  • e : events
  • g : global
  • i : indexes and iterators
  • m : member
  • p : pointer (and pp for pointer to pointer)
  • s : static member (e.g. sPrefChecked)
  • v : volatile

Private member prefix

How to distinguish a member variable is public or private? Using underscore '_' may be helpful.

  • private member: [PREFIX] + _ + [NAME]
    • m_age
    • m_phone
  • public member: [PREFIX] + [NAME]
    • mName

Using underscores may be risky

If you use underscore as first character, it might be risky. A leading underscore before a capital letter in a word is reserved. For example, _Foo is reserved, while _foo is not. However, there are other situation may make leading underscore before a lowercase infeasible.

The rules which did not change in C++11 from the 2003 C++ Standard:

  • Reserved in any scope, including for use as implementation macros:
    • identifiers beginning with an underscore followed immediately by an uppercase letter
    • identifiers containing adjacent underscores (or "double underscore")
  • Reserved in the global namespace:
    • identifiers beginning with an underscore
  • Also, everything in the std namespace is reserved. (You are allowed to add template specializations, though.)

See more here: underscore rules in C++ identifier.

Pros

  • No confusion between member and parameter
    • e.g., mName(name) instead of name(name)
  • Type is clearer then you can code faster and leave less comments
    • You don't waste time searching the variable's type and scope
    • You can distinguish the variable is global, local, static, pointer or not at a glance
  • Easy to guess how to use the variable:
    • e.g., No need to check what data type the dad is and try to figure out how to use it to get the dad's name. If we use pDad instead of dad, then we can easily know pDad->Name() is the answer.
  • Avoid generic(vague) names for usage:
    • e.g., iItem definitely shows it's the index/iterator for item counter to index or count.
  • Show less candidates in auto-complete lists with typing prefix

Cons

Need to think more here.....

Without Prefix

How to overcome the drawbacks mentioned above if we don't use prefix? Need to think more here.....

References

results matching ""

    No results matching ""