views:

213

answers:

3

Rarely in the regular codes I encounter the a single colon in classes for e.g.:

A::member():b(),c()
{
}

What is the importance of the single colon over here? Why is it used here? Is it mandatory sometimes? If so in which cases?

+12  A: 

A single colon in this context is used to signal that you are using an initializer list. An initializer list is used to:

  • Invoke base class constructors from a derived class
  • Initialize member variables of the class

As noted by others, an initializer list can only be used on a class constructor.

While it's also possible to initialize member variables in the body of the constructor, there are several reasons for doing so via the initializer list:

  • Constant pointers or references cannot be initialized from the body of the constructor
  • It is usually more efficient to use the initializer list as it will (from memory) only invoke the constructor for the member, rather than the constructor and assignment operator which can be costly for non-POD types.

Having said all of this, the formatting of your code is a bit odd. In the code that I usually work with, use of an initializer list would be indented like this:

A::A()
    :b(),
     c()
{
}

This makes it more clear to me that the : has no relation to the :: used to define class membership in A::A().

LeopardSkinPillBoxHat
member is always `A`
vava
@vava - thanks - updated.
LeopardSkinPillBoxHat
cpp_Beginner
@cpp_Beginner - The code as written will invoke the default constructors of the `b` and `c` members when constructing `A`. I don't know the types of these members but I'm assuming they are not POD types like int, long or char (IOW, a class with a constructor).
LeopardSkinPillBoxHat
+1  A: 

It is used to initialize references. In c++ you cannot assign or modify references, so in class they can only be "assigned" with semicolon syntax.

AareP
+1 for "In c++ you cannot assign or modify references, so in class they can only be "assigned" with semicolon syntax"
Sandeep
The word is initialized, not assigned. :] This requirement for an initialization list also applies to constant values.
GMan
A: 

The single colon specifies an initialization list, as the other couple of responses have already stated.

There are a number of gotchas about these lists and constructors in general. C++ does a reasonable job of generating default constructors and copy constructors but if you write your own, it leaves it up to you to handle everything:

  1. Be cautious of using use the word invoke because the presence on the list specifies which constructor will be used, it doesn't actually invoke that constructor. By that I mean that the order of invocation is governed solely by the class declaration. Most compilers will warn you if the initalizations are non in the same order as declared. The order is - base classes constructors in the order of declaration then member variables. It might help to think of it as a depth-first traversal up the class hierarchy.
  2. The items in the list are specifications of which member variable or base class constructors will be used - particularly important for writing copy constructors.
  3. Base classes that are not specified in the list will have their default constructor invoked. This is a major gotcha when you write your own copy constructor - you have to be careful to specify the base copy constructors otherwise they will not get their members copied.
  4. Members not in the list are not initialized
  5. As a corollary to 4. you therefore have a maintenance headache of having to remember to add members to each constructor.
  6. As a good practice, try not to rely on member initialization order anyway. You should try very hard to avoid code where one member must be initialized before another.
Andy Dent