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

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





PostPosted: Fri Jun 27, 2003 5:39 pm    Post subject: Constructor Initialization Reply with quote



Hi,

It seems I can influence how a base class is initialized beyond the
'normal' manner and I was wondering if someone can tell me why this.
Here's my example.

class A
{
public:
A(int a=1, int b=1, int c=1) : _a(a), _b(b), _c(c) {}
void print()
{ cout << _a << "," << _b << "," << _c << endl; }
private:
int _a, _b, _c;
};

class B : public virtual A
{
public:
B(int a=1, int b=1, int c=1) : A(a, b, c) {}
};

class C : public virtual B
{
public:
C(int a=1, int b=1, int c=1)
:
B(a, b, c),
A(2,2,2) // I can explicitly initialize A here and override
the default values
{}
};

main()
{
C c;
c.print();
}


thanks,
Mike

Back to top
Ron Natalie
Guest





PostPosted: Fri Jun 27, 2003 5:49 pm    Post subject: Re: Constructor Initialization Reply with quote




"Michael McKnerney" <michael.mcknerney (AT) baesystems (DOT) com> wrote

Quote:
Hi,

It seems I can influence how a base class is initialized beyond the
'normal' manner and I was wondering if someone can tell me why this.

Because you have virtual base classes. The most derived class must initialize
all the virtual bases. The initialization of A specified in the B constructor has no
bearing on the creation of C objects.

Quote:
main()
{

You must provide an int return here (even in C these days).



Back to top
Dhruv
Guest





PostPosted: Fri Jun 27, 2003 6:02 pm    Post subject: Re: Constructor Initialization Reply with quote



On Fri, 27 Jun 2003 17:39:03 +0000, Michael McKnerney wrote:

Quote:
Hi,

It seems I can influence how a base class is initialized beyond the
'normal' manner and I was wondering if someone can tell me why this.
Here's my example.
[snip]......



For virtual bases, the rule is different. The most derived class is
responsible for constructing the virtual base class, as opposed to its
immediate descendant in case of non-virtual bases.

HTH,
-Dhruv.







Back to top
Michael McKnerney
Guest





PostPosted: Fri Jun 27, 2003 6:07 pm    Post subject: Re: Constructor Initialization Reply with quote



Dhruv wrote:

Quote:
On Fri, 27 Jun 2003 17:39:03 +0000, Michael McKnerney wrote:

Hi,

It seems I can influence how a base class is initialized beyond the
'normal' manner and I was wondering if someone can tell me why this.
Here's my example.
[snip]......

For virtual bases, the rule is different. The most derived class is
responsible for constructing the virtual base class, as opposed to its
immediate descendant in case of non-virtual bases.


But wait a minute, if I remove the explicit initialization of A in C's
constructor list, A will get initialized by B.


Quote:

HTH,
-Dhruv.


Back to top
Ron Natalie
Guest





PostPosted: Fri Jun 27, 2003 6:40 pm    Post subject: Re: Constructor Initialization Reply with quote


"Michael McKnerney" <michael.mcknerney (AT) baesystems (DOT) com> wrote


Quote:
But wait a minute, if I remove the explicit initialization of A in C's
constructor list, A will get initialized by B.

No it will not. If you remove the explicit initialization, it will invoke the
default constructor. If A didn't have a default constructor, then you'd
get an error.



Back to top
Jim Fischer
Guest





PostPosted: Fri Jun 27, 2003 7:30 pm    Post subject: Re: Constructor Initialization Reply with quote

Michael McKnerney wrote:
Quote:

Dhruv wrote:


On Fri, 27 Jun 2003 17:39:03 +0000, Michael McKnerney wrote:


Hi,

It seems I can influence how a base class is initialized beyond the
'normal' manner and I was wondering if someone can tell me why this.
Here's my example.

[snip]......

For virtual bases, the rule is different. The most derived class is
responsible for constructing the virtual base class, as opposed to its
immediate descendant in case of non-virtual bases.

But wait a minute, if I remove the explicit initialization of A in C's
constructor list, A will get initialized by B.

Nope. If you remove the explicit initialization of A in C's initializer
list and then invoke the class C ctor,

C(int a=1, int b=1, int c=1)
: B(a,b,c)
{ }

the sequence of events (IIRC) is this:

1) Program invokes the C ctor
2) The C ctor implicitly invokes A's default ctor
3) The C ctor invokes 'B(a,b,c)' as specified in the initializer list of
the class C ctor. The B ctor does not invoke the A ctor.

So the class C ctor -- not the B ctor -- is still the entity that
invokes the class A ctor.


FWIW, if you rewrite your code a bit, this sequence of events will (IMO)
be easier to observe.

<example>
<code>

#include <iostream>
using namespace std;

class A {
public:
A(int a=1, int b=1, int c=1)
: a_(a), b_(b), c_(c)
{ cout << "A(" << a << ',' << b << ',' << c << ")n"; }

void print()
{ cout << a_ << ',' << b_ << ',' << c_ << 'n'; }

private:
int a_, b_, c_;
};

class B : public virtual A {
public:
B(int a=2, int b=2, int c=2)
: A(a, b, c)
{ cout << "B(" << a << ',' << b << ',' << c << ")n"; }
};

class C : public virtual B {
public:
C(int a=3, int b=3, int c=3)
// : A(4,4,4), B(a,b,c)
: B(a,b,c)
{ }
};

int main()
{
C c;
c.print();
}


<output>
A(1,1,1)
B(3,3,3)
1,1,1
</output>

</example>


Some side notes:

1) DO NOT use variable names that start with a leading underscore, e.g.,
'_a'. These names (and some others) are reserved for the
implementation's use -- e.g., the standard library, compiler-specific
language extensions, the OS's API, etc. So if you want to use
underscores to denote variable names, place the underscore at the end of
the name, 'a_', and not at the beginning.

2) In this code sample, class A's ctor is *always* invoked before class
B's ctor. This sequence holds even if you try (futilely) to specify the
base class ctor invocation sequence as B first, then A, in the class C
ctor initializer list:

C() : B(), A() { }

IOW, the compiler ignores the B,A sequence specified above, and
implicitly implements C's initializer list as A,B, i.e.,

C() : A(), B() { }

[n.b. Most compilers are nice enough to warn you when they implicitly
reorder the initializer list's arguments like this.]

--
Jim

To reply by email, remove "link" and change "now.here" to "yahoo"
jfischer_link5809{at}now.here.com



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.