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

时间:2016-10-14 16:06:20

标签: c++ inheritance

该计划的目的是生成扬声器音箱的仿真脚本。

因此,我有一个定义说话人的班级发言人。

包含所有机箱的公共参数的父类机箱。

具有自己特殊属性的儿童班。

使用多态和继承我获得了第一个完美无缺的程序但我需要每次都重新计算机箱的基本属性:

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中都相同。

因此,如果有办法,我现在会:

  • 创建父类

  • 进行首次初步一般性计算

  • 使用父参数创建子项(问题)

这意味着基本上是孩子=父母是被禁止的。 在这段代码的想法:

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

希望它清楚!

1 个答案:

答案 0 :(得分:1)

您描述的症状表明典型的 有一个 ,即继承与构图问题。

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

这允许您根据需要更改机箱系列。顺便说一下,这是 strategy pattern 的实现。

如果您确实需要保留原始设计,可以使用强制转换为父级并使用切片效果来覆盖父类:

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

但是我不建议这样做(请记住,首先要求在父母身上正确实施3规则)