a strange C++ syntax for me

O

Onix

I'm reading a code and this is what it looks like, pretty strange for
me:

class A {
size_t i_;
public:
A(size_t i): i_(i) {}
}

Is the constructor above is the same with the following?

A(size_t i) {
i_ = i;
}


Thanks
 
A

Abhishek Padmanabh

Onix said:
I'm reading a code and this is what it looks like, pretty strange for
me:

class A {
size_t i_;
public:
A(size_t i): i_(i) {}
}

Is the constructor above is the same with the following?

A(size_t i) {
i_ = i;
}

For POD type members, yes. Otherwise, the second form is assignment of those
members and not initialization. The first form is the preferred form for
initialization (i.e. using constructor initialization list), I believe. For
non-static const and reference members and parameterized base class
constructors, that preference becomes a necessity.
 
E

Erik Wikström

I'm reading a code and this is what it looks like, pretty strange for
me:

class A {
size_t i_;
public:
A(size_t i): i_(i) {}
}

Is the constructor above is the same with the following?

A(size_t i) {
i_ = i;
}

No, in the first case the value of i_ will be set _before_ entering the
constructor, while in the second case the value of i_ will be
undetermined when the constructor is created.

The first case uses an initialisation list which are very useful things,
learn to use them because sometimes you have to. Examples of these
cases are when you have const members:

class A {
const size_t i_;
public:
A(size_t i): i_(i) {} // Sets the value of i_
};

or when you derive from a class with a constructor that takes one or
more arguments:

class Base {
public:
Base(int i) {}
};

class A : public Base {
public:
A(int i): Base(i) {} // Runs Base's constructor
};

See also http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.6
 
B

brian tyler

You should always use a constructor list if possible as it is much
more efficient than constructing (ie default constructor) and then
assigning. One important thing to remember is that the elements in
your constructor list are initialised in the order that they were
declared, NOT the order you write them, so:

class A {
int i_;
int j_;
public:
A(int i): j_(i), i_(2*j_) {}
};

is undefined behaviour since i_ is constructed before j_, so at the
point the program executes 2*j_, j_ does not exist. However,

class A {
int i_;
int j_;
public:
A(int i): j_(2*i_), i_(i) {}
};

is absolutely fine, but it is confusing for a human to read, because
it looks like it is being done in the wrong order. Because of this,
when writing constructors, an excellent habit to get in to is to write
the variables in the same order as you have declared them. Most of the
time it makes no difference, but every now and again it will save you
from creating a rather subtle bug.


Brian.
 
R

Ron Natalie

Abhishek said:
For POD type members, yes. Otherwise, the second form is assignment of
those members and not initialization.

It's assignment even in the case of POD members. The only difference
is the dimwitted inconsistency that sometimes POD's don't get default
initialized.
 
A

Abhishek Padmanabh

It's assignment even in the case of POD members. The only difference
is the dimwitted inconsistency that sometimes POD's don't get default
initialized.

Sorry, Ron, I did not get you fully. The constructor body syntax is
assignment but the member remains unitialized. I refer to
[class.base.init]/4:

If a given non-static data member or base class is not named by a mem-
initializer-id (including the case where there is no mem-initializer-
list because the constructor has no ctor-initializer), then
-- If the entity is a non-static data member of (possibly cv-
qualified) class type (or array thereof) or a base class, and the
entity class is a non-trivial class, the entity is default-initialized
(8.5). If the entity is a non-static data member of a const-qualified
type, the entity class shall have a user-provided default constructor.
-- Otherwise, the entity is not initialized. If the entity is of
const-qualified type or reference type, or of a (possibly cv-
qualified) trivial class type (or array thereof) containing (directly
or indirectly) a member of a const-qualified type, the program is ill-
formed.

The "otherwise" part is the one that covers POD types. So, as per
above, they remain uninitialized until the assignment happens. Prior
to that assignment, no initialization has happened. So, using a member
initialization list or not for POD, doesn't make much difference. The
expression inside the body is assignment though. Is this what you are
trying to point out? What do you mean by "sometimes POD's don't get
default initialized"? In which cases does default initialization
happen for PODs (considering an empty initializer list)?
 
J

Juha Nieminen

Onix said:
I'm reading a code and this is what it looks like, pretty strange for
me:

class A {
size_t i_;
public:
A(size_t i): i_(i) {}
}

Is the constructor above is the same with the following?

A(size_t i) {
i_ = i;
}

In the case of size_t, probably. (Although in theory some compilers
might be able to optimize the first case more than the second one).
If the type of i_ was a class, then it's not the same thing.
 
R

Ron Natalie

Abhishek Padmanabh wrote:
\
The "otherwise" part is the one that covers POD types. So, as per
above, they remain uninitialized until the assignment happens.

Exactly. The POD never gets initialized. Despite your earlier
statement it is ALWAYS assignment POD ro not. The only difference
with PODs is that ther eis no earlier initialization (in CERTAIN
cases).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Staff online

Members online

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,007
Latest member
obedient dusk

Latest Threads

Top