10.6.2 组合

    某类以另一个类对象作为数据成员,称为组合,在逻辑上,如果类A是类B的一部分(a part of)或者说HAS-A(“有一个”),不要从类A派生出类B,而应当采用组合的方式,《高质量C++编程指南》中的这个范例很好地解释了组合的本质,如下所示。


    class Eye//眼睛类 { public: void Look(void);//功能:看 }; class Nose//鼻子类 { public: void Smell(void);//功能:闻 }; class Mouth//嘴巴类 { public: void Eat(void);//功能:吃 }; class Ear//耳朵类 { public: void Listen(void);//功能:听 }; class Head//头类 { public: void Look() { m_eye.Look(); } void Smell() { m_nose.Smell(); } void Eat() { m_mouth.Eat(); } void Listen() { m_ear.Listen(); } private://组合 Eye m_eye; Nose m_nose; Mouth m_mouth; Ear m_ear; };虽然代码很冗长,但这是一种正确的做法和设计,如果允许Head类从Eye、Nose、Mouth及Ear派生而来,那Head将自动具有Look、Smell、Eat及Listen的功能,如下所示。 class Head:public Eye,public Nose,public Mouth,public Ear { // };

    派生方式看似简洁、强大,但却会给后续设计带来很多问题,比如要添加一个割双眼皮的函数,对于组合来说,操作对象很明确,要操作的是成员m_eye,但如果按派生方式来操作,割双眼皮函数就会遇到问题,搞不好割的是头皮。