C++ member initialization question

Started by
6 comments, last by iMalc 17 years, 12 months ago
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
Advertisement
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
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.
-------Harmotion - Free 1v1 top-down shooter!Double Jump StudiosBlog
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;};
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]
"In order to understand recursion, you must first understand recursion."
My website dedicated to sorting algorithms
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]
"In order to understand recursion, you must first understand recursion."
My website dedicated to sorting algorithms
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;};


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.

"In order to understand recursion, you must first understand recursion."
My website dedicated to sorting algorithms

This topic is closed to new replies.

Advertisement