Categories
c++ c++-faq constructor ctor-initializer syntax

What is this weird colon-member (” : “) syntax in the constructor?

409

Recently I’ve seen an example like the following:

#include <iostream>

class Foo {
public:
  int bar;
  Foo(int num): bar(num) {};
};

int main(void) {
  std::cout << Foo(42).bar << std::endl;
  return 0;
}

What does this strange : bar(num) mean? It somehow seems to initialize the member variable but I’ve never seen this syntax before. It looks like a function/constructor call but for an int? Makes no sense for me. Perhaps someone could enlighten me. And, by the way, are there any other esoteric language features like this, you’ll never find in an ordinary C++ book?

4

  • 110

    An “ordinary c++ book” that doesn’t mention this is probably a c book where someone thought “++” would look cool on the cover …

    Nov 10, 2009 at 23:35

  • 95

    “you’ll never find in a ordinary C++ book”. Oh. Dear. Throw away your “ordinary C++ book” right now. Not out the window – somebody else might pick it up. Preferably shred it and put it for recycling. Done? Now consult stackoverflow.com/questions/388242/… to get a new book.

    Nov 10, 2009 at 23:36

  • 57

    This language feature is hardly esoteric. It’s a fairly major feature of object construction.

    Nov 10, 2009 at 23:36

  • 42

    In fact, far from esoteric, you often have no choice but to use initializer lists. For example, if your class contains a const member variable, or a reference, you have to use an initalizer list.

    Nov 10, 2009 at 23:42

246

It’s a member initialization list. You should find information about it in any good C++ book.

You should, in most cases, initialize all member objects in the member initialization list (however, do note the exceptions listed at the end of the FAQ entry).

The takeaway point from the FAQ entry is that,

All other things being equal, your code will run faster if you use initialization lists rather than assignment.

8

  • Knowing the terminology is critical – I’m jealous that I didn’t think of it.

    Nov 10, 2009 at 23:36

  • 1

    There are also a bunch of other reasons for using init lists. especially when the order of initialisation matters. It’s a shame it has such a stupid fake function call syntax.

    Nov 10, 2009 at 23:50

  • 21

    @mgb, the initialization list does not determine the order of initialization. Member variables are initialized in the order they are declared in the class, even if that differs from the order of the initializations on the constructor.

    – ScottJ

    Nov 11, 2009 at 0:26

  • 14

    @mgb: I don’t think it’s intended as a fake function call syntax. It’s initialization syntax, like int i(23);, std::vector<double> emptyVec(0);, std::vector<double> fullVec(10,23.);, etc. Only with the type removed, of course, because the type is in the member declaration.

    Nov 11, 2009 at 1:03

  • 1

    @Martin : It doesn’t have a function call syntax, it has a construction syntax (ala: new String(“Name”)). It fits in with the constructor better than Foo(int num) : m_Count = 5. Not to mention that classes must be constructed at this point anyway, since it’s initialized here. Foo(int num) : Bar = num, wouldn’t compile right. It just seems weird seeing Foo(int num) : m_Count(num), since primitive types aren’t constructed.

    Apr 22, 2011 at 20:33


246

It’s a member initialization list. You should find information about it in any good C++ book.

You should, in most cases, initialize all member objects in the member initialization list (however, do note the exceptions listed at the end of the FAQ entry).

The takeaway point from the FAQ entry is that,

All other things being equal, your code will run faster if you use initialization lists rather than assignment.

8

  • Knowing the terminology is critical – I’m jealous that I didn’t think of it.

    Nov 10, 2009 at 23:36

  • 1

    There are also a bunch of other reasons for using init lists. especially when the order of initialisation matters. It’s a shame it has such a stupid fake function call syntax.

    Nov 10, 2009 at 23:50

  • 21

    @mgb, the initialization list does not determine the order of initialization. Member variables are initialized in the order they are declared in the class, even if that differs from the order of the initializations on the constructor.

    – ScottJ

    Nov 11, 2009 at 0:26

  • 14

    @mgb: I don’t think it’s intended as a fake function call syntax. It’s initialization syntax, like int i(23);, std::vector<double> emptyVec(0);, std::vector<double> fullVec(10,23.);, etc. Only with the type removed, of course, because the type is in the member declaration.

    Nov 11, 2009 at 1:03

  • 1

    @Martin : It doesn’t have a function call syntax, it has a construction syntax (ala: new String(“Name”)). It fits in with the constructor better than Foo(int num) : m_Count = 5. Not to mention that classes must be constructed at this point anyway, since it’s initialized here. Foo(int num) : Bar = num, wouldn’t compile right. It just seems weird seeing Foo(int num) : m_Count(num), since primitive types aren’t constructed.

    Apr 22, 2011 at 20:33


17

That’s constructor initialisation. It is the correct way to initialise members in a class constructor, as it prevents the default constructor being invoked.

Consider these two examples:

// Example 1
Foo(Bar b)
{
   bar = b;
}

// Example 2
Foo(Bar b)
   : bar(b)
{
}

In example 1:

Bar bar;  // default constructor
bar = b;  // assignment

In example 2:

Bar bar(b) // copy constructor

It’s all about efficiency.

4

  • 7

    I wouldn’t say that this is about efficiency. It is about providing a way to initialize something that requires initialization, but cannot be default-initualized. For some reason people mention constants and references as the examples, while the most obvious example would be classes without default constructors.

    Nov 11, 2009 at 0:26

  • 1

    We’re both right; in his example you could argue for efficiency; for the const/reference/no default constructor issue it’s both efficiency and necessity. I upvoted an answer below because of it 🙂 [Farnsworth voice] It can do other things. Why shouldn’t it?

    – Josh

    Nov 11, 2009 at 4:19

  • 1

    Bar bar(); // default constructor Are you sure?

    Dec 27, 2015 at 14:55

  • @LightnessRacesinOrbit Just curious to know : What should that be according to you?

    Aug 2, 2019 at 11:01