C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Constructor initialization lists

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++)
View previous topic :: View next topic  
Author Message
Jef Driesen
Guest





PostPosted: Tue Dec 21, 2004 9:01 am    Post subject: Constructor initialization lists Reply with quote



Hello,

Suppose I have a class that looks like this:

class point {
protected:
unsigned int m_x, m_y; // OR unsigned int m_data[2];
public:
point();
point(unsigned int x, unsigned int y);
point(const point& p);
point& operator= (const point& p);
};

I know it is preferable to use initialization lists to initialize member
variables in a constructor:

point::point(unsigned int x, unsigned int y)
: m_x(x), m_y(y) {}
{
}

over assignments within the constructor body:

point::point(unsigned int x, unsigned int y)
{
m_x = x;
m_y = y;
}

In the second example, the default constructor for each data member is
invoked prior to the assignment in the constructor body. This will
result in lower performance (overhead of calling the unnecessary default
constructor).

But what if I replace the data members with an array? Now I can only use
assignment in the constructor body:

point::point(unsigned int x, unsigned int y)
{
m_data[0] = x;
m_data[1] = y;
}

My questions are:
(1) How is m_data initialized *before* the assignment in the body?
(2) Will this result in lower performance?


Back to top
Karl Heinz Buchegger
Guest





PostPosted: Tue Dec 21, 2004 9:15 am    Post subject: Re: Constructor initialization lists Reply with quote



Jef Driesen wrote:
Quote:

[snip]

But what if I replace the data members with an array? Now I can only use
assignment in the constructor body:

Right.
That's because arrays are what we call 'half baked types'. Arrays behave
differently in many aspects then other types.

Quote:

point::point(unsigned int x, unsigned int y)
{
m_data[0] = x;
m_data[1] = y;
}

My questions are:
(1) How is m_data initialized *before* the assignment in the body?

In this specific case: Not at all. int, unsigned int, char, float, double,
pointers (the 'builtin types') are *not* default initialized at all. They
simply contain what was in memory before the variable was placed there.
Usually its just garbage.

If you have an array of some class type however (eg. std::string), the default
constructor will be called for each array member.

Quote:
(2) Will this result in lower performance?

Depends: If you have an array of builtin type, then no. Usually this won't
result in lower performance. If however the default constructor is run for
each array member, then yes, most likely this will result in lower performance.
It depends on what the default constructor has to do.

--
Karl Heinz Buchegger
[email]kbuchegg (AT) gascad (DOT) at[/email]

Back to top
Bob Hairgrove
Guest





PostPosted: Tue Dec 21, 2004 9:30 am    Post subject: Re: Constructor initialization lists Reply with quote



On Tue, 21 Dec 2004 10:01:04 +0100, Jef Driesen
<jefdriesen (AT) hotmail (DOT) com.nospam> wrote:

Quote:
Hello,

Suppose I have a class that looks like this:

class point {
protected:
unsigned int m_x, m_y; // OR unsigned int m_data[2];
public:
point();
point(unsigned int x, unsigned int y);
point(const point& p);
point& operator= (const point& p);
};

I know it is preferable to use initialization lists to initialize member
variables in a constructor:

point::point(unsigned int x, unsigned int y)
: m_x(x), m_y(y) {}
{
}

over assignments within the constructor body:

point::point(unsigned int x, unsigned int y)
{
m_x = x;
m_y = y;
}

In the second example, the default constructor for each data member is
invoked prior to the assignment in the constructor body...

POD-types are NOT default constructed or initialized, their value is
undefined. In order to default initialize an unsigned int, you must
write:

point::point(unsigned int x, unsigned int y)
: m_x(), m_y()
{
m_x = x;
m_y = y;
}

Quote:
... This will result in lower performance (overhead of calling
the unnecessary default constructor).

For unsigned int, there is no performance loss to speak of. For
non-POD types, there might be ... depends on how the default
constructor (if any) and operator= (if overloaded) is implemented.
Also, it depends on how the compiler might optimize things. You have
to test to make sure.

Quote:
But what if I replace the data members with an array? Now I can only use
assignment in the constructor body:

point::point(unsigned int x, unsigned int y)
{
m_data[0] = x;
m_data[1] = y;
}

My questions are:
(1) How is m_data initialized *before* the assignment in the body?

It isn't. The compiler only reserves storage for an array of two
unsigned ints. Its contents are initially garbage. Of course, if the
members are of non-POD type, they must be default constructible, in
which case the default constructor is called once for each element.
But unsigned int is POD.

Quote:
(2) Will this result in lower performance?

See my remarks above. You won't know until you have tested it.

(I believe it was Donald Knuth who said: "Premature optimization is
the root of all evil.")

--
Bob Hairgrove
[email]NoSpamPlease (AT) Home (DOT) com[/email]

Back to top
Jacek Dziedzic
Guest





PostPosted: Tue Dec 21, 2004 12:22 pm    Post subject: Re: Constructor initialization lists Reply with quote

Bob Hairgrove wrote:
Quote:

My questions are:
(1) How is m_data initialized *before* the assignment in the body?


It isn't. The compiler only reserves storage for an array of two
unsigned ints. Its contents are initially garbage. Of course, if the
members are of non-POD type, they must be default constructible, in
which case the default constructor is called once for each element.
But unsigned int is POD.

I think the OP meant "how can I initialize m_data *before*..."
rather than "how is it that m_data gets initialized".

to the OP:
There is no way to initialize arrays inside the constructor
init-list. The same goes for members of structs.

Quote:
(2) Will this result in lower performance?

Don't worry about it if these are variables of built-in types.
Only if their default-construction is time-costly, you should
care.

HTH,
- J.

Back to top
Ron Natalie
Guest





PostPosted: Tue Dec 21, 2004 1:32 pm    Post subject: Re: Constructor initialization lists Reply with quote

Karl Heinz Buchegger wrote:

Quote:
In this specific case: Not at all. int, unsigned int, char, float, double,
pointers (the 'builtin types') are *not* default initialized at all. They
simply contain what was in memory before the variable was placed there.
Usually its just garbage.

Actually, they might or might not be default initialized. It depends how
the storage is allocated, such is the inconsistant nature of C++.

Back to top
Jef Driesen
Guest





PostPosted: Tue Dec 21, 2004 3:17 pm    Post subject: Re: Constructor initialization lists Reply with quote

Karl Heinz Buchegger wrote:
Quote:
Jef Driesen wrote:

[snip]

But what if I replace the data members with an array? Now I can only use
assignment in the constructor body:


Right.
That's because arrays are what we call 'half baked types'. Arrays behave
differently in many aspects then other types.


point::point(unsigned int x, unsigned int y)
{
m_data[0] = x;
m_data[1] = y;
}

My questions are:
(1) How is m_data initialized *before* the assignment in the body?


In this specific case: Not at all. int, unsigned int, char, float, double,
pointers (the 'builtin types') are *not* default initialized at all. They
simply contain what was in memory before the variable was placed there.
Usually its just garbage.

If you have an array of some class type however (eg. std::string), the default
constructor will be called for each array member.


(2) Will this result in lower performance?


Depends: If you have an array of builtin type, then no. Usually this won't
result in lower performance. If however the default constructor is run for
each array member, then yes, most likely this will result in lower performance.
It depends on what the default constructor has to do.


Thanks for the detailed answer.

Back to top
Jef Driesen
Guest





PostPosted: Tue Dec 21, 2004 3:26 pm    Post subject: Re: Constructor initialization lists Reply with quote

Bob Hairgrove wrote:
Quote:
POD-types are NOT default constructed or initialized, their value is
undefined. In order to default initialize an unsigned int, you must
write:

point::point(unsigned int x, unsigned int y)
: m_x(), m_y()
{
m_x = x;
m_y = y;
}

I didn't know I could default initialize a POD-type this way.

Quote:
(2) Will this result in lower performance?


See my remarks above. You won't know until you have tested it.

(I believe it was Donald Knuth who said: "Premature optimization is
the root of all evil.")

I understand that, but I wanted to know what the compiler is actually
doing with the array. And I think it won't hurt to remove unnecessary
initializations if possible.

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.