Question about constructors

G

gw7rib

Suppose I have the following code fragment:

class base {
private:
int m;

public:
base(int x) { m = x; }
};

class derived : public base {
private:
otherclass o;

public:
derived(int x) : base(x) { }
};

When I create a derived, is otherclass' constructor run or not? I did
an experiment and it was. However, I'd understood that it wouldn't be.
I thought that *if* I didn't define a default constructor for base
and/or derived, the computer would write one for me which initialised
all the members, but that, in the above case where I have defined a
non-default constructor, it wouldn't start writing constructors for me
(other than a copy constructor). Can you put me straight on this
please? (By the way, the behaviour of otherclass' constructor running
is what I want.)

Thanks in advance.
Paul.
 
J

John Carson

Suppose I have the following code fragment:

class base {
private:
int m;

public:
base(int x) { m = x; }
};

The preferred way to do this is:

base(int x) : m(x){}
class derived : public base {
private:
otherclass o;

public:
derived(int x) : base(x) { }
};

When I create a derived, is otherclass' constructor run or not? I did
an experiment and it was. However, I'd understood that it wouldn't be.
I thought that *if* I didn't define a default constructor for base
and/or derived, the computer would write one for me which initialised
all the members, but that, in the above case where I have defined a
non-default constructor, it wouldn't start writing constructors for me
(other than a copy constructor). Can you put me straight on this
please? (By the way, the behaviour of otherclass' constructor running
is what I want.)

The compiler doesn't write a default constructor for you. However, for the
constructor that you have written, a failure to explicitly initialize
members of class type in the initialization list means that the default
constructor of those members is called, i.e.,

derived(int x) : base(x) { }

is read as

derived(int x) : base(x), o() { }
 
M

mlimber

Suppose I have the following code fragment:

class base {
private:
int m;

public:
base(int x) { m = x; }
};

class derived : public base {
private:
otherclass o;

public:
derived(int x) : base(x) { }
};

When I create a derived, is otherclass' constructor run or not?

It is: non-POD types are default-constructed after base classes if they
are omitted from the initializer list. Compare this FAQ:

http://parashift.com/c++-faq-lite/ctors.html#faq-10.6
I did
an experiment and it was. However, I'd understood that it wouldn't be.
I thought that *if* I didn't define a default constructor for base
and/or derived, the computer would write one for me which initialised
all the members,

No members are initialized except what you initialize in the
constructor. Default constructors are called for non-POD types, but if
their constructors don't initialize their POD members, then they don't
get initialized either. Consider:

struct A
{
int i_, j_;
A() : i_(0) {} // i_ is initialized, j_ is not
};

struct B : A
{
int m_, n_;
A a_;
B() : m_(0) {} // Base class is implicitly default-constructed,
// a_ is implicitly default constructed,
// m_ is initialized, n_ is not
};

int main()
{
B b;
// ...
}


After B's constructor completes, the following is true:

* b.i_, b.m_, and b.a_.i_ are initialized to 0
* b.n_, b.j_, and b.a_.j_ are all uninitialized
but that, in the above case where I have defined a
non-default constructor, it wouldn't start writing constructors for me
(other than a copy constructor). Can you put me straight on this
please?

The compiler is not generating a default constructor for base or
derived, but it is calling the default constructor for otherclass.

Cheers! --M
 
G

gw7rib

Thank you to to both you (mlimber) and John Carson for your quick and
helpful answers.
It is: non-POD types are default-constructed after base classes if they
are omitted from the initializer list. Compare this FAQ:

http://parashift.com/c++-faq-lite/ctors.html#faq-10.6

Ah, now I see it - this FAQ is saying that if you don't use the
initialiser list then the members get default constructed, and if this
is not what you want then you have wasted time doing it before
assigning the desired values. The collorary being that, if the default
constructed values are fine, it is OK not to mention them in the
initialiser list or the constructor body. In this respect, the comment
"constructors should initialize as a rule all member objects in the
initialization list" is a little misleading.
 
M

mlimber

Thank you to to both you (mlimber) and John Carson for your quick and
helpful answers.


Ah, now I see it - this FAQ is saying that if you don't use the
initialiser list then the members get default constructed,

....*unless* the (non-static) members are POD types...
and if this
is not what you want then you have wasted time doing it before
assigning the desired values. The collorary being that, if the default
constructed values are fine, it is OK not to mention them in the
initialiser list or the constructor body. In this respect, the comment
"constructors should initialize as a rule all member objects in the
initialization list" is a little misleading.

No the rule is correct (assuming you add "or constructor body" to the
end). A constructor should either initialize a class' members
explicitly (as it must with POD types) or implicitly, which default
constructors handle.

Cheers! --M
 

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

Forum statistics

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

Latest Threads

Top