473,396 Members | 1,892 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

initialisation list in constructor

Hi everyone,

The FAQ at http://www.parashift.com/c++-faq-lit....html#faq-10.6
states that:

"Consider the following constructor that initializes member object x_
using an initialization list: Fred::Fred() : x_(whatever) { }. The
most common benefit of doing this is improved performance. For
example, if the expression whatever is the same type as member
variable x_, the result of the whatever expression is constructed
directly inside x_ — the compiler does not make a separate copy of the
object. Even if the types are not the same, the compiler is usually
able to do a better job with initialization lists than with
assignments.

The other (inefficient) way to build constructors is via assignment,
such as: Fred::Fred() { x_ = whatever; }. In this case the expression
whatever causes a separate, temporary object to be created, and this
temporary object is passed into the x_ object's assignment operator.
Then that temporary object is destructed at the ;. That's inefficient.

As if that wasn't bad enough, there's another source of inefficiency
when using assignment in a constructor: the member object will get
fully constructed by its default constructor, and this might, for
example, allocate some default amount of memory or open some default
file. All this work could be for naught if the whatever expression and/
or assignment operator causes the object to close that file and/or
release that memory (e.g., if the default constructor didn't allocate
a large enough pool of memory or if it opened the wrong file). "

I believe that if you write Fred::Fred() {x_ = whatever;} then
effectively what you're getting is Fred::Fred(): x_(whatever) {x_ =
whatever;}. This is what I think the last paragraph is saying (the
member object will get fully constructed by it's default constructor).

However, I don't see what the second paragraph is saying. If whatever
is a primitive, then no 'temporary object' will be created. If
whatever is an object, then a temporary object would have to be
created anyway in the initialisation example anyway:

Fred::Fred(): x_(WhateverClass()) {}

When is the temporary copy being referred to created?

in a 'normal function':

if we write:

Foo foo = bar;

then whether a temporary Bar object is created depends on the
definition of the Foo constructor:

Foo(Bar &); // no copy made
Foo(Bar); // copy made

Taras
Oct 23 '08 #1
6 3001
On Oct 23, 7:25*pm, Taras_96 <taras...@gmail.comwrote:
Hi everyone,

The FAQ athttp://www.parashift.com/c++-faq-lite/ctors.html#faq-10.6
states that:

"Consider the following constructor that initializes member object x_
using an initialization list: Fred::Fred() : x_(whatever) { }. The
most common benefit of doing this is improved performance. For
example, if the expression whatever is the same type as member
variable x_, the result of the whatever expression is constructed
directly inside x_ — the compiler does not make a separate copy of the
object. Even if the types are not the same, the compiler is usually
able to do a better job with initialization lists than with
assignments.

The other (inefficient) way to build constructors is via assignment,
such as: Fred::Fred() { x_ = whatever; }. In this case the expression
whatever causes a separate, temporary object to be created, and this
temporary object is passed into the x_ object's assignment operator.
Then that temporary object is destructed at the ;. That's inefficient.

As if that wasn't bad enough, there's another source of inefficiency
when using assignment in a constructor: the member object will get
fully constructed by its default constructor, and this might, for
example, allocate some default amount of memory or open some default
file. All this work could be for naught if the whatever expression and/
or assignment operator causes the object to close that file and/or
release that memory (e.g., if the default constructor didn't allocate
a large enough pool of memory or if it opened the wrong file). "

I believe that if you write Fred::Fred() {x_ = whatever;} then
effectively what you're getting is Fred::Fred(): x_(whatever) {x_ =
whatever;}. This is what I think the last paragraph is saying (the
member object will get fully constructed by it's default constructor).

However, I don't see what the second paragraph is saying. If whatever
is a primitive, then no 'temporary object' will be created. If
whatever is an object, then a temporary object would have to be
created anyway in the initialisation example anyway:

Fred::Fred(): x_(WhateverClass()) {}

When is the temporary copy being referred to created?
If you assign x_ in the ctor body instead of the init list, Fred's
ctor needs to allocate its members at the very least. This happens
before the ctor's body is processed.

....in the same breath ...
int temp(0);
int m = temp; // is a copy

note the difference now:
int temp(0);
int m;
m = temp; // is not a copy. assignment

The difference is that the first set of statements can be optimized
away, the assignment usually cannot.
>
in a 'normal function':

if we write:

Foo foo = bar;

then whether a temporary Bar object is created depends on the
definition of the Foo constructor:

Foo(Bar &); // no copy made
Foo(Bar); // copy made

Taras
Whether a temporary is created depends on whether its creation can be
optimized away or not.
In your second example, Foo(Bar); you'ld get 2 copies if it wasn't
optimized and you did use the init list (a temp is generated), 2
copies + op= if you didn't use the init list. In the first example
you'ld get a copy unless you were setting a member reference (no
temporary). Fortunately, that copy is usually optimized away.

For all intensive purposes, those paragraphs in faq-10.6 are relevent
since they give an overview of the difference between using the init
list and assignments. In reality the ctor, at the very least, will
allocate / reserve memory for its members before its body is
processed. Why not initialize those members using the init list then?

Copies are very fast usually. The same can't be said of allocation +
assignment.
Consider that most op= include an a self assignment check:

[http://www.parashift.com/c++-faq-lit...perators.html]

Fred& Fred::operator= (const Fred& f)
{
if (this == &f) return *this; // Gracefully handle self
assignment

// Put the normal assignment duties here...

return *this;
}

There is no reason not to use the init list. For a programmer: its
often a blessing. Take for example a simple way to zap the unitialized
pointer issue:

class P
{
int* p;
public:
P() : p(0) { }
...
};

The init list is more than just about efficiency.
Oct 24 '08 #2
Taras_96 wrote:
[..]
I believe that if you write Fred::Fred() {x_ = whatever;} then
effectively what you're getting is Fred::Fred(): x_(whatever) {x_ =
whatever;}. This is what I think the last paragraph is saying (the
member object will get fully constructed by it's default constructor).
Actually, it's more like

Fred::Fred() : x_() { x_ = whatever; }

'x_' is default-initialised before being assigned to.
However, I don't see what the second paragraph is saying. If [..]
You're basing your conclusions on a wrong premise, I'm afraid.
in a 'normal function':

if we write:

Foo foo = bar;

then whether a temporary Bar object is created depends on the
definition of the Foo constructor:

Foo(Bar &); // no copy made
Foo(Bar); // copy made
No. By definition, the form

TypeA objA = objB;

is a shorthand for

TypeA objA((TypeA(objB)));

The syntax with the '=' is *not* direct initialisation, it is
copy-intialisation from a *temporary object*, which is in turn
directly initialised from 'objB'.

In reality the compiler most likely skips the temporary and makes
the code analogous to

TypeA objA(objB);

but the difference is that the copy constructor in 'TypeA' *must*
exist and be accessible. That's the requirement.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Oct 24 '08 #3
In article <gd**********@news.datemas.de>, Victor Bazarov
<v.********@comAcast.netwrote:
Taras_96 wrote:
[..]
I believe that if you write Fred::Fred() {x_ = whatever;} then
effectively what you're getting is Fred::Fred(): x_(whatever) {x_ =
whatever;}. This is what I think the last paragraph is saying (the
member object will get fully constructed by it's default constructor).

Actually, it's more like

Fred::Fred() : x_() { x_ = whatever; }

'x_' is default-initialised before being assigned to.
[...]

....unless x_ is a built-in or POD type, in which case it has an
indeterminate value on entry to the constructor, before the assignment.
Oct 24 '08 #4
blargg wrote:
In article <gd**********@news.datemas.de>, Victor Bazarov
<v.********@comAcast.netwrote:
>Taras_96 wrote:
>>[..]
I believe that if you write Fred::Fred() {x_ = whatever;} then
effectively what you're getting is Fred::Fred(): x_(whatever) {x_ =
whatever;}. This is what I think the last paragraph is saying (the
member object will get fully constructed by it's default constructor).
Actually, it's more like

Fred::Fred() : x_() { x_ = whatever; }

'x_' is default-initialised before being assigned to.
[...]

....unless x_ is a built-in or POD type, in which case it has an
indeterminate value on entry to the constructor, before the assignment.
No, x_() default initialises it.

--
Ian Collins
Oct 24 '08 #5
In article <6m*************@mid.individual.net>, Ian Collins
<ia******@hotmail.comwrote:
blargg wrote:
In article <gd**********@news.datemas.de>, Victor Bazarov
<v.********@comAcast.netwrote:
Taras_96 wrote:
[..]
I believe that if you write Fred::Fred() {x_ = whatever;} then
effectively what you're getting is Fred::Fred(): x_(whatever) {x_ =
whatever;}. This is what I think the last paragraph is saying (the
member object will get fully constructed by it's default constructor).
Actually, it's more like

Fred::Fred() : x_() { x_ = whatever; }

'x_' is default-initialised before being assigned to.
[...]

....unless x_ is a built-in or POD type, in which case it has an
indeterminate value on entry to the constructor, before the assignment.

No, x_() default initialises it.
Sorry, I was referring to Taras_96's original example,

Fred::Fred() {x_ = whatever;}

noting that it is NOT exactly equivalent to Victor Bazarov's example,

Fred::Fred() : x_() { x_ = whatever; }

when x_ is a built-in or POD type. The difference would be hard to detect
in this case since x_ is immediately assigned a value.
Oct 24 '08 #6
On Oct 24, 1:25 am, Taras_96 <taras...@gmail.comwrote:
The FAQ
athttp://www.parashift.com/c++-faq-lite/ctors.html#faq-10.6
states that:
"Consider the following constructor that initializes member object x_
using an initialization list: Fred::Fred() : x_(whatever) { }. The
most common benefit of doing this is improved performance.
I'm going to disagree with the FAQ on this one. It's true that
doing so may result in improved performance, but that is rarely
the main motivation, or even a motivation. The most common
benefit of doing this is that it is cleaner; that you don't have
to worry about uninitialized or incorrectly initialized
variables in the body of your constructor. The general rule is
to never declare a variable without initializing it; member
variables are implicitlly declared before entering the
constructor, so logically, you want to initialize them before
entering the constructor.

Another frequent reason is that the type may not have a default
constructor (a lot of my types don't), so you have to initialize
it in the initializer list; otherwise, you get an error.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Oct 24 '08 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Samuele Armondi | last post by:
Hi, I'm writing some exception class for a project, and I've got a class called BasicException that looks like this: class BasicException { private: std::string Description; int Number; ...
106
by: A | last post by:
Hi, I have always been taught to use an inialization list for initialising data members of a class. I realize that initialsizing primitives and pointers use an inialization list is exactly the...
11
by: A | last post by:
Hi, It is recommened by many practitioners to always use an initialisation list to initialise data members of a class. However, I am having problems with such a list when passing...
2
by: Tim | last post by:
Please advise if you can. Presumably initialisation of members in member initialisation lists is perfomed by 'C' run-time startup. If the CRT was never started-up would those members be garbage?...
2
by: John Carson | last post by:
One routinely hears that the order of initialisation of objects with static storage duration in different translation units cannot in general be guaranteed. I have a question about one way to...
3
by: santosh | last post by:
Hello, I have const member in the class. How can I initialise these. I can not initialise in constructor ,(it is giving compilation error) What is the proper way to initialise. The code is given...
3
by: Raghu | last post by:
Hello all, Can somebody help me hopw to resolve teh probelm of aggregate initialisation in c++. Her eis the piece of code. #include<stdio.h> class MyTest { public:
4
by: Kevin Frey | last post by:
I have an assembly written in C++/CLI that also links in non-clr Native C++ (the C++/CLI wraps the Native C++ functionality). This assembly has an in-built tracing system that needs to be...
3
by: Pantokrator | last post by:
Hi all, I've got a question about the scope of the constructor initialisation list. First of all, let me explain my classes: // ***************************************************** class...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.