将父数据成员值传递给子类

Pass parent data members value to child class

本文关键字:子类 值传 数据成员      更新时间:2023-10-16

程序的目的是生成扬声器外壳的模拟脚本。

这样我就有了一个类speaker,它定义了speaker。

父类enclosure,包含所有enclosure的公共参数。

具有自身特殊属性的子类。

使用多态性和继承,我获得了第一个程序,它工作得很好,但我需要每次重新计算外壳的基本属性:

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;
}

在我的程序中,父类的成员数据可以给子类。我的意思是,Enclosure的盒维数在每个子类bassreflexclosedbox中都是相同的。

因此,如果有一种方法,我现在会:

  • 创建父类

  • 进行第一次初始一般计算

  • 用父参数创建子参数

表示child=parent,这是不允许的。在这个代码的思想中:

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;
}

希望这是清楚的!

您描述的症状表明存在典型的is-a vs has-a,即继承vs组合问题。

在c++中,原则是创建子对象。孩子的构建过程为:

  • 首先构建一个封闭的父对象
  • 则构造子节点的成员
  • ,最后,执行子构造函数体以完成构造。

一旦您对这个逻辑有问题,它就表明继承可能不是最好的方法。OOP中通常的建议是优先选择组合而不是继承。原则上,只有在对象的性质不变的情况下,才应该使用继承。

由于我不熟悉你的领域,这里有一个典型的和更熟悉的例子:

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 

在您的情况下,我理解Enclosure有一些一般参数,但是有一个形状因子(我称之为这个家族)决定了波如何与环境通信,以及其他一些功能。

在这种情况下,你可以输入:

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() { ... };  
};

这允许您根据需要更改附件族。顺便说一下,这是策略模式的实现。

如果你真的需要保持你原来的设计,你可以使用转换到父类并利用切片效果来覆盖父类:

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

然而,我不建议这样做(请记住,它首先需要在父节点上正确执行3规则)