initialization within constructor

R

rona

Hi everyone,

Could someone tell us why the below code compiles and works? Is it
legal in the constructor of class B?

Cheers

Ronny

---------------------------------

#include <iostream>

using namespace std;

class a {
int x;
public:
void show() { cout<<x<<endl; }
a(int xx) : x(xx) {}
a() {}
};

class B {
a ma;
public:
B(int xx);
void disp() { ma.show(); }
};

B::B(int xx) {
ma = a(xx);
}


int main() {
B b(3);
b.disp();



return 0;
}
 
V

Victor Bazarov

rona said:
Could someone tell us why the below code compiles and works?

Probably because it's well-formed...
Is it
legal in the constructor of class B?

Yes, why do you ask? What throws you off?
---------------------------------

#include <iostream>

using namespace std;

class a {
int x;
public:
void show() { cout<<x<<endl; }
a(int xx) : x(xx) {}
a() {}
};

class B {
a ma;
public:
B(int xx);
void disp() { ma.show(); }
};

B::B(int xx) {
ma = a(xx);

This is an assignment from a temporary 'a' object (which is in turn
initialised from the 'xx') to the member 'ma'.

You could achieve the same effect by doing

B::B(int xx) {
ma = xx;
}

or, even better, by

B::B(int xx) : ma(xx) {
}
int main() {
B b(3);
b.disp();



return 0;
}

V
 
M

mlimber

rona said:
Hi everyone,

Could someone tell us why the below code compiles

Yes, because there are no compile-time errors.
and works?

That's harder to determine. What are the requirements for the program?
Is it
legal in the constructor of class B?

Yes. See below.
Cheers

Ronny

---------------------------------

#include <iostream>

using namespace std;

class a {
int x;
public:
void show() { cout<<x<<endl; }
a(int xx) : x(xx) {}
a() {}

This is bad because x is left unitialized and could remain so if the
user isn't careful. You probably added it so class B would compile.
};

class B {
a ma;
public:
B(int xx);
void disp() { ma.show(); }
};

B::B(int xx) {
ma = a(xx);
}

This is legal, but you should delete the default constructor for class
a and use an initialization list here (see
http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.6). It works
because there is an implicit = operator generated for class a, and you
"convert" the integer xx to an "a" object by creating a temporary
object of type a. (Actually, it would also work if the line read "ma =
xx;" since that same constructor would be called implicitly.)

Cheers! --M
 
R

rona

Victor said:
Probably because it's well-formed...


Yes, why do you ask? What throws you off?

Couple of reasons:
1- I knew using a constructor initializer list was the best option.
Eckel's book sounded as if it was the ONLY option. My mistake.
2- Still confused about what happens to the initial storage allocated
to the member ma. When ma is first declared within the class definition
for B, is memory allocated to ma. If yes, what happens to this memory
after "ma = a(xx);" ?

Cheers
 
V

Victor Bazarov

rona said:
Couple of reasons:
1- I knew using a constructor initializer list was the best option.
Eckel's book sounded as if it was the ONLY option. My mistake.

No big deal. Happy to help.
2- Still confused about what happens to the initial storage allocated
to the member ma. When ma is first declared within the class
definition for B, is memory allocated to ma. If yes, what happens to
this memory after "ma = a(xx);" ?

Memory stays where it is. You have a default c-tor in 'a' which leaves
the 'x' member uninitialised. Just before this statement, 'ma.x' has
indeterminate value (you can examine it in the debugger). Here, two
things happen: a temporary is constructed with 'xx' as the constructor
argument, and the [compiler-generated] assignment operator is called
which invokes the assignment semantics on all members, which for you
means 'ma.x = sometemporaryobject.x'

[..]

V
 
A

Abhishek Pamecha

rona said:
Hi everyone,

Could someone tell us why the below code compiles and works? Is it
legal in the constructor of class B?

Cheers

Ronny

---------------------------------

#include <iostream>

using namespace std;

class a {
int x;
public:
void show() { cout<<x<<endl; }
a(int xx) : x(xx) {}
a() {}
};

class B {
a ma;
public:
B(int xx);
void disp() { ma.show(); }
};

B::B(int xx) {
ma = a(xx);
}


int main() {
B b(3);
b.disp();



return 0;
}

Use
B::B(int xx): ma(xx) {
}

instead.
you are assigning a temporary object otherwise.
 
A

Andrey Tarasevich

rona said:
...
1- I knew using a constructor initializer list was the best option.
Eckel's book sounded as if it was the ONLY option. My mistake.

It would be the only option if class 'a' had no default constructor. But
it does have one.

If you remove the default constructor declaration from 'a' (the 'a() {}'
line), the code will no longer compile and a constructor initializer
list will become the only option of initializing 'ma' from 'B'.
2- Still confused about what happens to the initial storage allocated
to the member ma. When ma is first declared within the class definition
for B, is memory allocated to ma.

Yes, it is allocated. Initialization of that 'b' object begins with the
implicit initialization of 'ma' through a call to the default
constructor of class 'a' (mentioned above). The default constructor of
'a' does nothing, i.e. no physical initialization takes place ('ma'
still contains garbage after it), but conceptually 'ma' is "initialized".
If yes, what happens to this memory after "ma = a(xx);" ?

A temporary object of type 'a' is created and initialized with the
'a::a(int)' constructor. Then this temporary object is copied into 'ma'
using the copy assignment operator 'a& a::eek:perator=(const a&)'. Since
you didn't declare this operator explicitly, the compiler will declare
and define it for you implicitly.
 

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

Members online

No members online now.

Forum statistics

Threads
474,161
Messages
2,570,892
Members
47,431
Latest member
ElyseG3173

Latest Threads

Top