Confused on class member variable initialization

R

Randy

Hi,

When a class contains another class as a member variable, e.g.,

class ClassA
{
int a;

public :

ClassA(int a1, int a2){a = a1 - a2;};
~ClassA();
};

class ClassB
{
int b;
ClassA classA;

....
};

what exactly happens to member variable classA when an instance of B is
created? More
specifically,

1. How do you initialize classA within ClassB's constructor?

2. What happens if you provide no initialization of classA
within ClassB's constructor?

--Randy
 
T

TB

Randy sade:
Hi,

When a class contains another class as a member variable, e.g.,

class ClassA
{
int a;

public :

ClassA(int a1, int a2){a = a1 - a2;};
~ClassA();
};

class ClassB
{
int b;
ClassA classA;

...
};

what exactly happens to member variable classA when an instance of B is
created? More
specifically,

1. How do you initialize classA within ClassB's constructor?

ClassB::ClassB() : classA(2,3) {

}
2. What happens if you provide no initialization of classA
within ClassB's constructor?

Error. Since ClassA doesn't have a default constructor it must
be initialized.

TB
 
R

Randy

Thanks TB. Is there an alternate syntax to

ClassB::ClassB() : classA(2,3) {

namely, one that can be used inside the body of
the constructor? If one had numerous class
member variables that required initializing, this
could become ugly.

I'm thinking it would be simply

ClassB::ClassB()
{
classA(2,3);
}

no?

--Randy
 
T

TB

Randy sade:
Thanks TB. Is there an alternate syntax to

ClassB::ClassB() : classA(2,3) {

namely, one that can be used inside the body of
the constructor? If one had numerous class
member variables that required initializing, this
could become ugly.

Provide a default constructor and then initialize
it through a secondary interface.
I'm thinking it would be simply

ClassB::ClassB()
{
classA(2,3);
}

no?

No. When the execution point enters the constructor body the object
is fully constructed. Only initialization occurs therein,
despite its name. And, it's not that ugly =)

TB
 
J

Jim Langston

Randy said:
Thanks TB. Is there an alternate syntax to

ClassB::ClassB() : classA(2,3) {

namely, one that can be used inside the body of
the constructor? If one had numerous class
member variables that required initializing, this
could become ugly.

I'm thinking it would be simply

ClassB::ClassB()
{
classA(2,3);
}

no?

No. If absolutely can't, or refuse, to use the initialization list, then
use a pointer instead.

class ClassB
{
ClassA* classA;
ClassB() { classA = new ClassA(2, 3); };
};

But honestly, once you start using initialization lists it becomes more
natural. I also at first didn't like them and would find ways around them,
now I initialize EVERYTHING in my class in an initialization list.

Although, to be honest, I would really like a cleaner way of doing this:

CGUIElement::CGUIElement( std::string OpenFileName, std::string
ClosedFileName,
JCOLOR ColorKey,
GUIType WhatType,
unsigned long X, unsigned long Y,
unsigned int inX1, unsigned int inY1,
unsigned int inX2, unsigned int inY2,
unsigned int textX, unsigned int textY,
unsigned int textX2, unsigned int textY2) : OpenNotifier(this),
OpenObserver(this),
CloseNotifier(this), CloseObserver(this),
CloseOnOpenNotifier(this), CloseOnOpenObserver(this),
IsOpen(false), IsLoaded(false),
NotifyMsg(0),
Type(WhatType),
BitmapX(X), BitmapY(Y),
X1(inX1), Y1(inY1),
X2(inX2), Y2(inY2),
TextX(textX), TextY(textY),
TextX2(textX2), TextY2(textY2),
TextWidth(0), TextHeight(0)
{
....

especially when that's combined with the declaration:

CGUIElement( std::string OpenFileName, std::string ClosedFileName,
JCOLOR ColorKey,
GUIType WhatType,
unsigned long X, unsigned long Y,
unsigned int ThisX1 = 0, unsigned int ThisY1 = 0,
unsigned int ThisX2 = 0, unsigned int ThisY2 = 0,
unsigned int textX = 0, unsigned int textY = 0,
unsigned int textX2 = 0, unsigned int textY2 = 0);
 
J

JustBoo

Although, to be honest, I would really like a cleaner way of doing this:

CGUIElement::CGUIElement( std::string OpenFileName, std::string

[snipped function with many parameters]

I'm not claiming this is better, just better for me. :)

I do a few different things in this situation. One is I create a POD
(struct) with all the parameters in it and pass that around.

CGUIElement::CGUIElement( POD& params );

I find I can then make my functions smaller by dividing and conquering
the beast. It could add complexity though by having the POD updated
and /or read in several different places. I've never found it a
problem though.

It's just to make the code look cleaner really. Obviously, the same
amount of work (init and such) needs done somewhere.

If I have a large amount of params to pass around I've also made them
full-blown classes and then have some of the work (validation for
example) done internal to the class itself. A Parameter class as it
were. I think this follows a Design Pattern that I can't think of
right now. :) In fact, I think it was a design pattern that gave me
the idea.

I understand with some API's this might not be possible.

"Only in our dreams are we free. The rest of the time we need wages."
- Terry Pratchett
 

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
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top