Sign in to follow this  
jujumbura

C++ member initialization question

Recommended Posts

Hello all, I have a question in regards to initializing a struct through the constructor. My situation was something like this:
struct A
{
int m_baseInt;
};


struct B : public A
{
B( int baseInt, int subInt ) : m_baseInt( baseInt ), m_subInt( subInt ){}
int m_subInt;
};
The compiler throws an error here. It tells me that "m_baseInt is not a member of B". This seems odd to me, aren't all member variables in structs public by default? So shouldn't I have access to a public member of my base class? After poking around the net for initialization examples, I replaced it with the following code that I found:
struct A
{
A( int baseInt ) : m_baseInt( baseInt ){}
m_baseInt;
};


struct B
{
B( int baseInt, int subInt ) : A( baseInt ), m_subInt( subInt ){}
m_subInt;
};
So, is this the way I should initialize the members of my base class? And if so, why don't I have access to those member variables when the constructor is executing? I'd appreciate any insight. Thanks much, jujumbura

Share this post


Link to post
Share on other sites
You can only initialise members in the initialisation list that are exact members of the class the initialisation list is in. This does not include base classes as in your case. Here the second way is how it is to be done.

Dave

Share this post


Link to post
Share on other sites
The 2nd way is correct. You can't initialize members of A in the initializer list of your ctor for B.

You do have access to the members of A in the ctor of B though, just not he initializer list.

Share this post


Link to post
Share on other sites
Quote:
Original post by jujumbura
Hello all,

I have a question in regards to initializing a struct through the constructor. My situation was something like this:

struct A
{
int m_baseInt;
};

struct B : public A
{
B( int baseInt, int subInt ) : m_baseInt( baseInt ), m_subInt( subInt ){}
int m_subInt;
};


The compiler throws an error here. It tells me that "m_baseInt is not a member of B". This seems odd to me, aren't all member variables in structs public by default? So shouldn't I have access to a public member of my base class?

After poking around the net for initialization examples, I replaced it with the following code that I found:


struct A
{
A( int baseInt ) : m_baseInt( baseInt ){}
m_baseInt;
};

struct B
{
B( int baseInt, int subInt ) : A( baseInt ), m_subInt( subInt ){}
m_subInt;
};


So, is this the way I should initialize the members of my base class? And if so, why don't I have access to those member variables when the constructor is executing?

I'd appreciate any insight.
Thanks much,

jujumbura


The problem with your first is that you can't initialise another class/structs member variables otherwise they would be initialised twice which could be a big mistake for some objects.

Blaze02: The second is incorrect and I'll show you why
Edit: I have just realised that you meant incorrect, not correct.

What is wrong with your second bit of code is that B must derive from A and you must have a member variable in B that uses A


struct B : A // Public by default
{
B(int baseInt, int subInt) : m_structA(baseInt), m_subInt(subInt)

A m_structA;
int m_subInt;

};

Share this post


Link to post
Share on other sites
Quote:
Original post by Adam Hamilton
struct B : A // Public by default
{
B(int baseInt, int subInt) : m_structA(baseInt), m_subInt(subInt)

A m_structA;
int m_subInt;

};
That is in fact quite wrong.
You should not declare an instance of A as a member of B. B already inherits from A and thus already contains A's member variables.

The second code jujumbura posted was more correct.

Edit: Nearly didn't notice that B wasn't derived from A, so it wasn't totally correct.

[Edited by - iMalc on April 18, 2006 3:13:43 AM]

Share this post


Link to post
Share on other sites
Quote:
Original post by jujumbura
So, is this the way I should initialize the members of my base class? And if so, why don't I have access to those member variables when the constructor is executing?
Your second code snippet is almost correct, you just forgot to derive B from A. I almost missed that.
As a matter of fact, you do have access to the member variables of the base class in this case, in fact you could theoretically do this:
struct B : public A
{
B( int baseInt, int subInt ) : m_subInt( subInt ) { m_baseInt = baseInt}
int m_subInt;
};
However I would advise against it, as that practice is not as efficient in general.

The sole purpose of initialiser lists is to initialise the classes member variables, not to initialise its parent's member's variables. Class B shouldn't have to know how to initialise class A, that's class A's job. Hence it initialises its single member vaiable, and then asks its parent to do the same (giving it a little extra information to do the job). That way if the constructor for A was a little more complicated you wouldn't end up duplicating its code within B's constructor also.[cool]

I hope that makes sense.

Edit: Eeek, you also missed the type (int) from in front of the member variables in the second case. Are we blind today or what![totally]

Share this post


Link to post
Share on other sites
You are right iMalc. I must have been thinking about derived and non derived and somehow amalgamated them into one. Thankyou for pointing that out so quickly.

I have revised the code.

Because A does not have a default constructor, you MUST call the constructor of A in B's initialiser list otherwise you will get a compiler error.


struct A
{
A(int baseInt) : m_baseInt(baseInt)
{}

int m_baseInt;
};

struct B : public A
{
B(int baseInt, int subInt) : A(baseInt), m_subInt(subInt)
{}

int m_subInt;
};



Share this post


Link to post
Share on other sites
Quote:
Original post by Adam Hamilton
You are right iMalc. I must have been thinking about derived and non derived and somehow amalgamated them into one. Thankyou for pointing that out so quickly.

I have revised the code.

Because A does not have a default constructor, you MUST call the constructor of A in B's initialiser list otherwise you will get a compiler error.

struct A
{
A(int baseInt) : m_baseInt(baseInt)
{}

int m_baseInt;
};

struct B : public A
{
B(int baseInt, int subInt) : A(baseInt), m_subInt(subInt)
{}

int m_subInt;
};

You mention a good point about their being no default constructor, I had overlooked that in the example I gave.
The code you have now posted is exactly what jujumbura was looking for.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this