Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

What's the difference?

Status
Not open for further replies.

tas2826

Programmer
Jul 6, 2005
26
0
0
US
I am curious about something dealing with constructors in dialog classes. I have seen a certain way of doing the constructor and I wonder if it actually buys anything. Here is what I am talking about:

FOO::FOO(CWnd* pParent /*=NULL*/)
: CDialog(FOO::IDD, pParent),
m_pSomeObject( NULL ),
m_bSomeBoolean( false ),
m_iSomeInt( 0 ),
m_sSomeString( "" )
{
//{{AFX_DATA_INIT(FOO)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}

Now m_pSomeObject, m_bSomeBoolean, m_iSomeInt, and m_sSomeString are member variables of the class. So, they are being initialized. Is this method of defining a constructor better than doing it this way?

FOO::FOO(CWnd* pParent /*=NULL*/)
: CDialog(FOO::IDD, pParent)
{
//{{AFX_DATA_INIT(FOO)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
m_pSomeObject = NULL;
m_bSomeBoolean = false;
m_iSomeInt = 0;
m_sSomeString = "";
}

It is not importaint that it be a dialog class, this is just where I am seeing it used. I am just wondering what the advantages of one over the other are, or if there are advantages?


Thanks,
Troy
 
In your case above, the benefits are purely style and habit based. POD types don't really have any performance benefits from being initialized in the initializer list (the first code) versus inside the constructor body (the second code).

However, some other objects types will have minor (and occasionally major) performance improvements by using the initializer list, because classes not in the initializer list will have their default constructor called. When they are initialized in the constructor body, the assignment operator (or whatever initialization method is used) is called. If you use the constructor in the initialization list, then you only initialize the object once.

A simple example is a string class. If you initialize the string in the initializer list, it starts off with the correct memory allocation to fit the string data. If you do it inside the constructor body, then the string will be default constructed, which may allocate a small amount of memory, and then it may have to reallocate when it is assigned a new value in the constructor body.

There are times when you must use the initializer list. These include reference members, const members, and class members without default constructors.

The only case I know of that where an initializer list would be bad is if you are passing the this pointer to the member being constructed. It is dangerous to use this before the constructor body is reached.

Because it is rarely wrong to use the initializer list, and it can be required or more efficient in some cases, it is considered good style to always use the initializer list, even for simple POD types like those in your example.
 
I believe initializer lists are more efficient because of the default constructor issue that uolj mentioned, but also because there are no temporary variables created the way they are in the second example.
Some newer compilers may be able to optimize the second constructor to be as efficient as the first, but I wouldn't rely on that being the case always.
 
Oops, I was thinking of a different situation, shown below, but even that was wrong. I just tried compiling the following two classes and looking at the assembly code. Low and behold, the assembly is EXACTLY the same! :eek:
Code:
ClassA::ClassA( int iNum, float fNum )
{
   m_IntNum   = iNum;
   m_FloatNum = fNum;
}
Code:
ClassA::ClassA( int iNum, float fNum )
: m_IntNum( iNum ),
  m_FloatNum( fNum )
{}
 
One thing to consider though is that the order in which the members are defined defines the order in which they are initialized.

Code:
  class Foo
  {
    ...
    int mBar;
    int mFoo;
  };

  // Gives the impression that mFoo is initialized before
  // mBar, but that is not true. mBar is initialized first
  // following the order in the class declaration
  Foo::Foo():mFoo(0),mBar(0) {}

For trivial members this isn't an issue, but might very well be an issue if you have some kind of relationship between the members.

To reduce confusion and mistakes follow the rule:
[highlight]Member initialization order shall be the same as member declaration order.[/highlight]




/Per
[sub]
www.perfnurt.se[/sub]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top