Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C++
class myclass
{
  int my1,my2;
  public:
  myclass(int num1,int num2) : my1(num1),my2(num2)
  {
 
  }
 
};
 
What does the statement in the constructor : my1(num1),my2(num2) mean?
Can you please help me understand what does this do?
 
Thank you very much!
Posted 4-Oct-12 4:01am
Comments
n.podbielski at 4-Oct-12 9:08am
   
Isn't it parents constructors cals?
NexusNemesis at 4-Oct-12 9:15am
   
I don't have idea, all I know is that it is a copy constructor thing...Can you explain?
Richard MacCutchan at 4-Oct-12 9:18am
   
Nothing to do with copy constructors, see my answer.
Richard MacCutchan at 4-Oct-12 9:17am
   
No.
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

It means set the value of variable my1 to the input parameter num1, and the value of my2 to the input parameter num2. This information is freely available in the MSDN reference[^].
It's just an alternative way of writing:
  myclass(int num1,int num2)
  {
      my1 = num1;
      my2 = num2;
  }
 
  Permalink  
v2
Comments
Marcus Kramer at 4-Oct-12 10:03am
   
+5. We both thought alike on that one didn't we.
Legor at 4-Oct-12 10:54am
   
I have to argue that the two variants are not allways the same. According to Scott Meyers "Effective C++" using a initialisation list in most cases is more effective then assigning the values in the constructor body. This is because doing the assignment in the body actually translates to a call to the standard constructor followed by the copy-assignement operator while using the initialization list only calls the copy-constructor.
Richard MacCutchan at 4-Oct-12 11:44am
   
You are quite correct, but the end result is the same as far as most people are concerned.
Richard MacCutchan at 4-Oct-12 11:50am
   
I just looked more closely at the generated code for the two cases, using the OP's class and it is exactly the same in both cases.
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

It is one way in which member variables can be initialized from within the constructor. It is really no different than writing the constructor this way.
myclass(int num1, int num2)
{
   my1 = num1;
   my2 = num2;
}
  Permalink  
Comments
Richard MacCutchan at 4-Oct-12 10:26am
   
Great minds, I believe. :)
Legor at 4-Oct-12 10:54am
   
I have to argue that the two variants are not allways the same. According to Scott Meyers "Effective C++" using a initialisation list in most cases is more effective then assigning the values in the constructor body. This is because doing the assignment in the body actually translates to a call to the standard constructor followed by the copy-assignement operator while using the initialization list only calls the copy-constructor.
Marcus Kramer at 4-Oct-12 11:25am
   
You are correct, but it would take a pretty impressive piece of code to show any performance hit and at the end of the constructor call the object will be in the same state regardless of the process used. My personal preference has been to use the inline initialization rather than the body initialization.
Stefan_Lang at 5-Oct-12 11:22am
   
The main difference is that initializer lists use direct initialization and the assignments as given here use copy construction. If the members in question are classes and there is a performance difference between the conversion and copy constructors of that class, then you get a performance difference.
 
P.S.: found the article I got it from at: http://www.gotw.ca/gotw/036.htm
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 3

The list following the ':' after the constructor parameter list is called initializer list or initialization list. It is a comma-separated list of 'initializers', where each item defines the intialization of either a member variable of the class, or a base class of the class. In case of a member variable, the name of the variable is followed by a single argument (in brackets) that is used to construct the variable via copy-construction. In case of a base class, a variable length argument list (again, in brackets) may be passed that corresponds to any constructor definition of that base class.
 
Also, the order of initialization may depend on what you put in the initializer list (but I think this does not affect member variables). I can't pinpoint the article I once downloaded about that, but IIRC the order of construction is:
1. virtual base classes
2. base classes (closest level first)
3. member variables
 
I'm not sure about 1. and 2. but I'm quite sure member variables in initializer lists are always initialized last, i. e. you can use data and functions from your base classes for the purpose of initializing your member variables in the initialization list.
 
That said, it's probably better not to do anything that depends on the order of initialization, if only to not confuse your colleagues Wink | ;)
  Permalink  
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 4

Most often it doesn't matter whether you use member initializer lists or assignments inside the body of your constructor. For example in your case you can perform the initialization of your int members from both the initializer list and the body of your constructor. However sometimes you can intialize a member only from the initializer list, and sometimes you HAVE TO explicitly initialize some members in the initializer list if you don't want to get a compile error!
class class_with_default_ctor
{
public:
    // this can act as a default ctor
    class_with_default_ctor(int _i=0)
        : i(_i)
    {}
 
    int i;
};
 
class class_without_default_ctor
{
public:
    class_without_default_ctor(int _i)
        : i(_i)
    {}
 
    int i;
};
 
class something
{
};
 
class test
{
public:
    test(something& sg)
        // You don't have to initialize m_class_with_default here but
        // you can do that if the default constructor doesn't do what
        // you want and other constructors are available. If you
        // don't call a default constructor here explicitly then
        // the compiler automatically calls the default constructor
        // of the class before the body of your ctor is executed so
        // later modifying the value of m_class_with_default in the
        // body of your constructor means that you initialize twice:
        // once by calling its default constructor and then when you
        // change it. You can avoid this double initialization by
        // explicitly calling a different constructor from the
        // initializer list, you can't do this from the ctor body.
        : m_class_with_default(5)
        // The following initializations are all MANDATORY and they
        // can be performed only from the initializer list! Not
        // initializing any of these from the initializer list leads
        // to a compile error!
        , m_class_without_default(6)
        , m_const_int(7)
        , m_const_something_ref(sg)
        , m_something_ref(sg)
    {
    }
 
private:
    class_with_default_ctor m_class_with_default;
    class_without_default_ctor m_class_without_default;
    const int m_const_int;
    const something& m_const_something_ref;
    something& m_something_ref;
};
 
You also HAVE TO use the initializer list to initialize a base class that doesn't have a default constructor if you don't want a compile error and you may want to use it to execute something else than the default ctor of the base class (same as with the member variables).
  Permalink  
v3

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 OriginalGriff 6,045
1 DamithSL 4,601
2 Maciej Los 4,087
3 Kornfeld Eliyahu Peter 3,480
4 Sergey Alexandrovich Kryukov 3,260


Advertise | Privacy | Mobile
Web01 | 2.8.141220.1 | Last Updated 4 Oct 2012
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100