Jump to content
  • Advertisement
Sign in to follow this  
gretty

C++ Inheritance Q's

This topic is 2800 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi

I am trying to experiment with inheritance in c++ & I have some questions:

- If a child object calls it's parents constructor inside its own constructor, is it possible to call the parent constructor AFTER I have done some code inside the child constructor OR can I not choose WHEN the parent constructor is performed?

- (Referring to the child object) In my code below why doesn't myX get initialised to 2 (it becomes zero)?

- If I call the function setX( int x ); from within the child class, why doesn't it change the child functions myX value also. This is a problem for me, because I have a parent class PopUpDialog & I want to calls its function CalculateWindowPos() from inside a child class of PopUpDialog called MovingPopUpDialog. And that fucntion will(should) set the MovingPopUpDialogs member varaibles to a certain value.

Any solutions & advice would be really helpful.



class Parent
{
public:
Parent( int x );
void printVal();
void setX( int a );

private:
int myX;

};


class Child : public Parent
{
public:
Child( int x, int y );
void printVal();
void setX( int a );

private:
int myX;
int myY;

};



Parent :: Parent( int x )
: myX(x)
{
std::cout << "Parent constructor running \n";
}


Child :: Child( int x, int y )
: myY(y), Parent( x )
{
std::cout << "Child constructor running \n";

/*
Is it possible to perform some code THEN call the parent constructor?
For eg,

int abc = 9;

Parent :: Parent(x);

*/

}


void Parent :: printVal()
{
std::cout << "x= " << myX <<std::endl;
}


void Child :: printVal()
{
std::cout << "x= " << myX << "y= " << myY << std::endl;

}


void Parent :: setX( int a )
{
myX = a;
}


void Child :: setX( int a )
{
Parent :: setX( a );
}






Main


int main()
{

Parent p(1);
Child c(2, 3);


p.printVal();
c.printVal();

c.setX( 9 );
c.printVal();

system("PAUSE");
return 0;
}



Share this post


Link to post
Share on other sites
Advertisement
1) All base class constructors are executed before the body of the derived class constructor is entered.

2) Because you don't initialize it. You only initialize the parent's myX.

3) Because you don't assign to the child myX.

Share this post


Link to post
Share on other sites
The order of the initializer list is the order that it is declared in the class.
This means, if my class is:

class MyClass
{
public:
MyClass(int x, int y);

int y; //Since y is declared first... it gets initialized first.
int x;
};

Child::Child( int x, int y )
x(x), y(y) //Even if we specifically tell 'x' to be initalized first,
//really, 'y' gets initialized since it's declared first.
{
/*Also notice how I can use the same name (x) for both the parameter and the member.
(Constructors allow this in the initalization list - don't use it within the parameters
though, or by default the class will use the parameter 'x' instead of the member 'x')*/

}



This also means, all inheritted classes always get initialzed before the child classes variables get initialized.

Quote:

Is it possible to perform some code THEN call the parent constructor?
For eg,

int abc = 9;

Parent :: Parent(x);


Nope (although I vagually recall them adding this in C++0x, but I might be mistaken there). But you can go like this:
Parent :: Parent(int x)
{
this->Init(x); //Call a custom function.
}


Child :: Child(int x)
: Parent(x) //Parent initialized here.
{
int abc = 9;

Parent :: Init(x); //Parent's Init function called here - not really initializing it
//(it was already initialized), but the result is the same.
}




It's not as appealing to me though. [smile]

Quote:
- (Referring to the child object) In my code below why doesn't myX get initialised to 2 (it becomes zero)?

- If I call the function setX( int x ); from within the child class, why doesn't it change the child functions myX value also?


The problem is you are declaring myX twice. Think of this: You have myX in the parent class... and the child inherits myX from the parent class and the child also declares it's own myX. So now you have two 'myX' variables.

One is named Parent::myX, and one is named Child::myX. Inside the parent, it can only see Parent::myX. Inside the child, it can see both of them, and by default, chooses it's own one (Child::myX). You can explicitly say "Parent::myX = 123" if you like, but what you really want in this case, is to not give the child any myX, and just let it inherit the parent's.

This is also why calling setX isn't working.
Watch:
void Parent :: setX( int a )
{
//In setX, we are setting the value of the parent's myX.
Parent::myX = a;
}

void Child :: printVal()
{
//In the Child's printVal(), we are printing the value of the indentically named, but completely different, child's myX!
std::cout << "x= " << Child::myX << "y= " << Child::myY << std::endl;

Parent :: setX( 9 );
}

By the way, you don't have to say Parent :: setX( 0 ). The compiler is smart enough for you to just say setX( 0 ), unless Child also has a function called 'setX()' that takes a single int as a parameter.

Share this post


Link to post
Share on other sites
Thanks for your replies guys

In theory I understand everything you guys are saying but I dont have experience on how to practically code this (for example how to code so that the Child object can have its myX var initialised or set).


Taking your advice I deleted the declaration "int myX;" from the Child class declaration. But now when I compile I get an error in the Childs printVal(); function because I am "accessing int Parent :: myX which is private".


Could you show me how I can alter my example code to allow myself to set a Childs myX value?


This is what I think I should do, but I get alot of compiler errors when I alter the code to this:

class Parent
{
public:
Parent( int x );
void printVal();
void setX( int a ); // maybe the only way I can get this to work is
// to make this funct virtual?

private:
int myX;

};


class Child : public Parent
{
public:
Child( int x, int y );
void printVal();

private:
int myY;

};



Parent :: Parent( int x )
: myX(x)
{
std::cout << "Parent constructor running \n";
}


Child :: Child( int x, int y )
: myY(y), Parent( x ) // leave this as is, & the childs myX var should be initialised when the parent constructor is called
{
std::cout << "Child constructor running \n";
}


void Parent :: printVal()
{
std::cout << "x= " << myX <<std::endl;
}


void Child :: printVal() // leave this as is, because the compiler will know I am referring to the the childs myX var(which is really the parents), correct?
{
std::cout << "x= " << myX << "y= " << myY << std::endl;

}


void Parent :: setX( int a ) // leave as is, because when I call this function as child c.setX( 9 ); the compiler will know to call this function, correct?
{
myX = a;
}





My original code:

class Parent
{
public:
Parent( int x );
void printVal();
void setX( int a );

private:
int myX;

};


class Child : public Parent
{
public:
Child( int x, int y );
void printVal();
void setX( int a );

private:
int myX;
int myY;

};



Parent :: Parent( int x )
: myX(x)
{
std::cout << "Parent constructor running \n";
}


Child :: Child( int x, int y )
: myY(y), Parent( x )
{
std::cout << "Child constructor running \n";

/*
Is it possible to perform some code THEN call the parent constructor?
For eg,

int abc = 9;

Parent :: Parent(x);

*/

}


void Parent :: printVal()
{
std::cout << "x= " << myX <<std::endl;
}


void Child :: printVal()
{
std::cout << "x= " << myX << "y= " << myY << std::endl;

}


void Parent :: setX( int a )
{
myX = a;
}


void Child :: setX( int a )
{
Parent :: setX( a );
}


Share this post


Link to post
Share on other sites
I only skimmed the code, so this may or may not be relevant, but you can make a member variable of a parent class accessible from derived classes by marking it as protected rather than private. (Another option, which may be preferable in some cases, would be to make the variable private but provide protected accessors through which it can be queried and/or modified.)

Share this post


Link to post
Share on other sites
The private keyword prevents the item (method, variable, etc) from being accessed from anywhere except the class it's declared in. The protected keyword is preferred when you want to grant access to child classes while still preventing access from other locations. Regardless of the access you set, child classes always contain all the variables of their parent. Also, since the parent class has a setter method, setX() which is public, the child class is always able to call that in order to change the variable. But if you leave the variable as private, you'd also need to provide a getX() method for the child to read the variable.

Your parent and child classes both contain a printVal() function. The child object hides it's parent's printVal() method, meaning the child one is called by default. But you can deliberaly call the parent version if you need to.
In your main function:

Child c(2, 3);
c.printVal(); // Child's printVal
c.Parent::printVal(); // Parent's printVal

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!