views:

340

answers:

9

What does the colon operator (":") do in this constructor? Is it equivalent to MyClass(m_classID = -1, m_userdata = 0);?

class MyClass {
public:

    MyClass() : m_classID(-1), m_userdata(0) { 
    }

    int m_classID;
    void *m_userdata;
};
A: 

It denotes the beginning of an initialiser list, which is for initialising member variables of your object.

As to: MyClass(m_classID = -1, m_userdata = 0);

That declares a constructor which can take arguments (so I could create a MyClass using MyClass m = MyClass(3, 4), which would result in m_classID being 3, and m_userdata being 4). If I were to pass no arguments to the MyClass constructor, it would result in an equivalent object being created to the version with the initialiser list.

Dominic Rodger
A: 

In this case: Yes, ist is equivalent because only primitive types are concerned.

If the members are classes (structs) then you should prefer the initialization list. This is because otherwise the objects are default constructed and then assigned.

SebastianK
+1  A: 

It's a initialization list. In your example, it's rather something like this (something like this - doesn't mean it's equivalent in all cases):


class MyClass {

public:

    MyClass(){
         m_classID = -1;
         m_userdata = 0;
    }

    int m_classID;
    void *m_userdata;

};
Ravadre
+5  A: 

This is an initialization list, and is part of the constructor's implementation.

The constructor's signature is:

MyClass();

Which means of course that you have a parameterless constructor - hence, one which will be called by default when you write MyClass someObject;

The part : m_classID(-1), m_userdata(0) is called initialization list. It is a way to initialize some fields of your object (all, if you want) with values of your choice, instead of leaving them as undefined. Later, you will enter the constructor body (empty, in your example). There you can do more assignments if you want, but once you have entered it all the fields have already been initialized - either to random, unspecified values, or to the ones you chose in your initialization list.

Daniel Daranas
+2  A: 

It signals the beginning of an initializer list.

Also it is not equivalent to MyClass(m_classId=-1,m_userData=0). This is attempting to define a constructor with 2 parameters that have default values. However the values lack types and it should not compile at all.

JaredPar
+1  A: 

That is called the member initialization list. It is used to call the superclass constrctors, and give your member variables an initial value at the time they are created.

In this case, it is initializing m_classID to -1 and m_userData to NULL.

It is not quite equivalent to assigning in the body of the constructor, because the latter first creates the member variables, then assigns to them. With the initialization, the initial value is provided at the time of creation, so in the case of complex objects, it can be more efficient.

JohnMcG
It's also sometimes a must to use the member initialization list. If you have a member variable that is a reference you must set it using the member initialization list.
Skurmedel
+1  A: 

It isn't precisely an operator. It's a part of the syntax for a constructor.

What it is saying is that following it will be a list of member variables and their initial values.

Constant members have to be initialized this way. Non-constants can be initialized here too, as long as it can be done with a single expression. If it takes more code than that to initialize a member, you have to put actual code between the {}'s to do it.

A lot of people like to put pretty much all their constructor code in the initilizer list. I have one co-worker who regularly writes classes with several screens of initilizers, and then puts "{}" for the constructor code.

T.E.D.
+1  A: 

Its the start of an initialiser list which sets member variables during the construction of the object. Your example "MyClass(m_classID = -1, m_userdata = 0);" is not possible as you have not defined the correct constructor and you would not be able to access the member variables in the parameter list anyway... you could have something like:

MyClass( int classId = -1, void* userData = 0 ) : m_classID(classId), m_userdata(userData) {}

The initialiser list is considered better than:

MyClass( int classId = -1, void* userData = 0 ) {
    m_classID = classId;
    m_userdata = userData;
}

Google for more info.

Patrick
A: 

It is an initialization list.

By the time you get in the body of the constructor, all fields have already been constructed; if they have default constructors, those were already called. Now, if you assign a value to them in the body of the constructor, you are calling the copy constructor. That is inefficient, because two constructors end up being called instead of one.

So in the case of primitive types like int, there's no advantage compared to assigning them in the body of the constructor. In the case of objects that have a constructor, it is a performance optimization because it avoids calling both the default and the copy constructor.

An initialization list is necessary if one of the fields is a reference because a reference can never be null, not even in the brief time between object construction and the body of the constructor. The following raises error C2758: 'MyClass::member_' : must be initialized in constructor base/member initializer list

class MyClass {
public :
    MyClass(std::string& arg) {
        member_ = arg;
    }
    std::string& member_;
};

The the only correct way is:

class MyClass {
public :
    MyClass(std::string& arg) 
        : member_(arg) 
    {
    }
    std::string& member_;
};

See the C++ FAQ for a better discussion.

Dr_Asik
It's often mis-believed that if you have a reference member, that you *have* to define a constructor with an constructor initializer list. But that's not quite true. A simple `MyClass m = { arg };` will work fine, too.
Johannes Schaub - litb
litb: but then you are more or less required to use m = {arg}; arent' you? In my eyes, being able to do MyClass m(ref) is quite desired.
Skurmedel
@Skurmedel, i agree. But that doesn't mean it's the only way to do it, of course.
Johannes Schaub - litb
Indeed; anyway I didn't know you could do that, so good comment :).
Skurmedel
Thanks, I didn't know about that. Although a quick search on MSDN revealed that this syntax has very limited use: see compiler error C2552. http://msdn.microsoft.com/en-us/library/0s6730bb(VS.80).aspx
Dr_Asik