views:

423

answers:

8

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 << (new 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 a ordinary C++ book?

+25  A: 

It's an initialization list. You should find information about it in any good C++ book.

You should, in most cases, initialize all member objects in the 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.

James McNellis
Knowing the terminology is critical - I'm jealous that I didn't think of it.
Mark Ransom
+1 for the FAQ part
NawaMan
Couldn't have said it better myself.
Stephen Newell
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.
Martin Beckett
You should *always* initialize member variables, unless it's *really* okay for them to contain garbage after their parent object is instantiated (e.g., I/O buffers). Because you're guaranteed to get garbage in them if you don't.
Loadmaster
@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
@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.
Steve Jessop
+1  A: 

You are correct, this is indeed a way to initialize member variables. I'm not sure that there's much benefit to this, other than clearly expressing that it's an initialization. Having a "bar=num" inside the code could get moved around, deleted, or misinterpreted much more easily.

Aric TenEyck
The benefit is that it's usually more efficient. And, in some cases, such as when you have `const` member variables, or member variables that are references, you *have* to use an initializer list.
Charles Salvia
+2  A: 

I don't know how you could miss this one, it's pretty basic. That's the syntax for initializing member variables or base class constructors. It works for plain old data types as well as class objects.

Mark Ransom
Written on one line inside the declaration like that it's easy to not spot it as an init list
Martin Beckett
+5  A: 

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.

Josh
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.
AndreyT
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
+4  A: 

This is called an initialization list. It is an alternate way of initializing class members. There are benefits to using this instead of simply initializing the members in the body of the constructor, but if you are initializing class members which are constants or references they must be initialized via the initialization list.

LeopardSkinPillBoxHat
+1 for mention of const/reference initialisation!
Josh
+2  A: 

This is an initialization list. It'll initialize the members before the constructor body is run. Consider

class Foo {
 public:
   string str;
   Foo(string &p)
   {
      str = p;
   };
 };

vs

class Foo {
public:
  string str;
  Foo(string &p): str(p) {};
};

In the first example, str will be initialized by its no-argument constructor

string();

before the body of the Foo constructor. Inside the foo constructor, the

string& operator=( const string& s );

will be called on 'str' as you do str = p;

Wheras in the second example, str will be initialized directly by calling its constructor

string( const string& s );

with 'p' as an argument.

nos
+1  A: 

there is another 'benefit'

if the member variable type does not support null initialization or if its a reference (which cannot be null initialized) then you have no choice but to supply an initialization list

pm100
+1  A: 

The other already explained to you that the syntax that you observe is called "constructor initializer list". This syntax lets you to custom-initialize base subobjects and member subobjects of the class (as opposed to allowing them to default-initialize or to remain uninitialized).

I just want to note that the syntax that, as you said, "looks like a constructor call", is not necessarily a constructor call. In C++ language the () syntax is just one standard form of initialization syntax. It is interpreted differently for different types. For class types with user-defined constructor it means one thing (it is indeed a constructor call), for class types without user-defined constructor it means another thing (so called value-initialization for empty ()) and for non-class types it again means something different (since non-class types have no constructors).

In your case the data member has type int. int is not a class type, so it has no constructor. For type int this syntax means simply "initialize bar with the value of num" and that's it. It is done just like that, directly, no constructors involved, since, once again, int is not a class type of therefore it can't have any constructors.

AndreyT