0

if I have these classes :

class A
{
    int x,y;
    public: 
        A(const int &x,const int &y):x(x),y(y){} 
};
class B:public A
{
    int z;
    public :
       B(const int &x,const int &y,const int &thez):z(thez),A(x+z,y+z)
};

I want to initialize z in class B before calling A's constructor but as I discovered from debug A's constructor always get called first no matter where it's put.

The real goal of this is to calculate rotational inertia of a Player class(the Player found in foosball) that is composed of three cubes( head, body, and legs), the three cubes are initialized in the Player constructor and Player inertia is initialized in Body's constructor(Body is the parent of Player).

My problem is that inertia of the Player depends on the inertias of the cubes, I calculate them and I want to sum them and call parent on it but I can't sum them without initializing the cubes(they're nothing before initializing).

So how to do this ?

PS

I know I can just put the relations and sum, well yes but it's veeeery long, the constructor will get ugly easily if I did that, I'm considering this as last resort only.

niceman
  • 2,653
  • 29
  • 57

3 Answers3

2

Besides whether it is a good idea or not to do so: If you want to have a derived class member initialized before the base class members, you can use the base-from-member-idiom: just put the corresponding member into another base class and make sure it is initialized first.

class A
{
    int x,y;
    public: 
        A(const int &x,const int &y):x(x),y(y) {} 
};

class Z
{
    int z;
    Z(const int &thez): z(thez) {}
};

class B: public Z, public A
     //  ^^^^^^^^ 
     // Z must come before A
{
    public :
       B(const int &x,const int &y,const int &thez): Z(thez), A(x+z,y+z) {}
};

This, the base class Z -- and particularly its member z -- is going to be initialized before the members of A.

Disclaimer: in general, be careful with multiple inheritance and its diamond of death.

Community
  • 1
  • 1
davidhigh
  • 14,652
  • 2
  • 44
  • 75
  • this will solve the problem , but I don't want multiple inheritance , I know I'll regret it later – niceman Jun 03 '15 at 20:09
  • @niceman: not definitely: keep it constrained to the bare essentials, and maybe derive `private`ly. See here what [Stroustroup says about MI](https://isocpp.org/wiki/faq/multiple-inheritance#mi-not-evil). You don't have many other chances, otherwise derived class members will get initialized after base class members. – davidhigh Jun 03 '15 at 20:45
1

The other answers have given some suggestions for how to work around your issue - my suggestion would be to think about the problem slightly differently.

This seems like a case where using composition instead of inheritance might be a good idea.

In your case, you said that "Body" is the parent of "Player", which leads me to think that this may be a design choice that could be reconsidered. I would consider thinking of it like this instead:

  • Create an abstract parent class called something like ThingWithInteria, which defines the API for getting the inertia of an object.
  • Create a BodyPart class, which contains the values relevant to each body part (in your case, perhaps this would be mass and distance from center?), and which implements the ThingWithInteria API using some simple calculations on those values.
  • Change the Player class to also inherit from ThingWithInertia. It would contain a number of BodyParts ("head", "body" and "legs" in your example).
  • In the constructor for Player, initialize each of the BodyParts before entering the main body of the function constructor. It's then easy to compute the overall inertia as a function of the inertias of the individual parts.

This class hierarchy reflects the fact the relationship between Player and BodyPart is not an "is a" relationship, it's a "has a" (or "has some") relationship. While they may share a common API for accessing the inertia, the way that they implement it is different because they represent fundamentally different things.

While this doesn't solve the specific programming question that you asked about how to initialize member variables before calling the parent constructor, I thought it would be worth mentioning in case others find this question due to making some similar design choice which has led them to this point.

sheltond
  • 1,877
  • 11
  • 15
0

If you are not modifying "z" before you pass it to the parent class then you should just pass "z" to the parent class like this:

class B:public A
{
    int z;
    public :
       B(const int &x,const int &y,const int &thez):A(x+thez,y+thez), z(thez)
};

This way the parent class gets the "z" value added to its "x" and "y" and you also get to store the value of "z" for later use.

Another way is to use the derived class constructor to modify the inherited values like this:

class B:public A
{
    int z;
    public :
       B(const int &x,const int &y,const int &thez):A(x,y), z(thez)
       {
           //modifications to z
           x +=z;
           y +=z;
       }
};

This only works if you are not doing other modifications in the parent constructor.

Josh Edwards
  • 369
  • 1
  • 4