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

2018-12-30 22:22发布

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

12条回答
素衣白纱
2楼-- · 2018-12-30 22:48

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.

查看更多
爱死公子算了
3楼-- · 2018-12-30 22:49

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.

查看更多
梦醉为红颜
4楼-- · 2018-12-30 22:51

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

查看更多
无色无味的生活
5楼-- · 2018-12-30 22:52

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.

查看更多
裙下三千臣
6楼-- · 2018-12-30 22:58

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.

查看更多
其实,你不懂
7楼-- · 2018-12-30 22:59

Not mentioned yet on this thread: since C++11, the member initializer list can use list-initialization (aka. "uniform initialization", "braced initialization"):

Foo(int num): bar{num} {}

which has the same semantics as list-initialization in other contexts.

查看更多
登录 后发表回答