Boulgour
Boulgour

Reputation: 23

Pass parent data members value to child class

The aim of the program was to generate simulation scripts of loudspeaker enclosures.

Thus I have a class speaker which define the speaker.

A parent class enclosure which contains common parameters of all enclosures.

Children class which have specials properties of themselves.

Using polymorphism and inheritance I obtained the first program which work perfectly fine but i need to recalculate basics properties of enclosure each time:

class speaker
{     
}
class Enclosure
{ 
        int m_boxHeight;
        speaker * m_speakerBass;//...
        public://some functions
}
class closedBox : public Enclosure
{        
    public: 
        closedbox(speaker &speakerbass):Enclosure(speakerbass)//    some functions            
    protected:
        int paramclosed1;//...            
 }

int main()
{    
    speaker speakerbass;

    cout <<endl<< "Please choose in the available enclosure proposals" << endl;
    cout << "1 Closed box enclosure" << endl;
   // cout << "2 Bass reflex enclosure" << endl;
   // cout << "3 and so on..." << endl;
    int choice;
    cin>>choice;
          switch (choice)
      {
         case 1:
            closedbox * ClBox2Simu;
            ClBox2Simu= new closedbox(speakerbass);       
            delete ClBox2Simu;
            break;
         case 2:
             //... same but with bassreflex class child    
            break;

         default:
            cout<<"Then good bye";

      }
    return 0;
}

In the case of my program the member data of the parent class could be given to the childen . I mean, the box dimension of the Enclosure are the same in each child class bassreflex or closedbox.

Thus I would now if there is a way to:

Which mean basically child=parent which is forbidden. In the idea of this code:

class speaker
{
    public:        //    some functions
    protected:
        int fs;
        int paramSpeaker2;            //...    
}
class Enclosure
{    
    public:            //some common function
    protected:
        int m_boxHeight;
        speaker *m_speakerBass //...    
}
class closedBox : public Enclosure
{    
    public:
        closedbox();  //    some functions
    protected:
        int paramclosed1;  //...    
}
class bassreflex : public Enclosure
{    
    public:
        bassreflex();  //    some functions
    protected:
        int paramclosed1;   //...    
}

int main()
{    
    Enclosure initialBox;// calculate dimension,choose speaker...

            closedbox * ClBox2Simu;
            ClBox2Simu= initialBox;//  child= parent which is forbidden
            //do stuff concerning closedbox
            delete ClBox2Simu;

            bassreflex * BassReflex2Simu;
            BassReflex2Simu= initialBox; //forbidden
            //do stuff concerning bassreflex
            delete BassReflex2Simu;

             //... and so on for other child class using enclosure

      delete initialBox
    return 0;
}

Hope it's clear!

Upvotes: 1

Views: 2272

Answers (1)

Christophe
Christophe

Reputation: 73376

The symptoms that you describe suggest a typical is-a vs. has-a, i.e. inheritance vs. composition problem.

In C++, the principle is to create the child objects. The construction process of the child is:

  • first an enclosed parent object is constructed
  • then the members of the child are constructed
  • and finally, the child constructor body is executed to finish the construction.

As soon as you have problem with this logic, it suggest that the inheritance is probably not the best approach. The usual advice in OOP is to prefer composition over inheritance. Inheritance should in principle only be used if the nature of the object doesn't change.

As I'm not familiar with your domain, here a typical and more familiar example:

class animal {}; 
class cat : public animal {};  // ok:  a cat will always remain an animal

class person {}; 
class employee : public person {}; // bad idea: a person could have several job
                                  // or change job or (hopefully temporarily) without job

// possible alternative
class job_t { string title, company; date from,to; ... }; 
class person { vector<job_t> jobs; ... };  // very flexible 

In your case, I'd understand that Enclosure has some general parameters, but there is a shape factor (I'd call this family) that determines how waves are communicated to the environment,and some other functions.

In this case you could go for:

class EnclosureFamily {
    public: 
       double compute_volume_in_room() = 0;  // abstract; 
}; 
class Enclosure
{    
    public:            //some common function
       double compute_volume_in_room() {
           return f->compute_volume_in_room();   // forwarding 
       }
    protected:
        int m_boxHeight;
        speaker *m_speakerBass; 
        EnclosureFamily *f;  // ok, but smart ponters should be preferred
}; 
class BoxEnclosure : public EnclosureFamily {
    public: 
       double compute_volume_in_room() { ... };  
};

This allows you to change the enclosure family as you want. By the way, this is an implementation of the strategy pattern.

If you really need to keep your original design, you could overwrite the parent class using casting to parent and making use of slicing effect:

*static_cast<Enclosure*>(BassReflex2Simu)= initialBox; // not forbidden but slicing

However I wouldn't advise going that way (keep in mind that it first would require proper implementation of the rule of 3 on the parent)

Upvotes: 1

Related Questions