如何在组合中的运行时更改成员对象?

时间:2012-12-16 07:02:34

标签: c++ oop composition

来自思考C ++ Vol。 1 (P-33):

  

组合具有很大的灵活性。会员   你的新课程的对象通常是私人的,制作它们   使用该类的客户端程序员无法访问。这个   允许您在不打扰现有成员的情况下更改这些成员   客户代码。
   您还可以在运行时将成员对象更改为   动态更改程序的行为。遗产,   接下来描述的,因为没有这种灵活性   编译器必须对创建的类放置编译时限制   继承。

如何在合成中更改运行时的成员对象?
Aren在写入类声明时包含的对象是什么?

class car
{
private:
engine obj;
}

因此,类car包含类engine的对象。我们如何在运行时更改它?

或者我错过了一些观点?

3 个答案:

答案 0 :(得分:6)

尝试使用指向成员对象的指针:

class car {
    engine *obj;
}

现在,您可以在运行时选择是否使用rotary_enginev8_engineflux_capacitor_engine的实例。

当然,您可能希望使用类似unique_ptrshared_ptr的内容来管理成员对象的所有权和生命周期。

答案 1 :(得分:1)

这确实是一个模糊的陈述。

组合定义了has-a关系,即 carengine 。您可以更换汽车的引擎,汽车仍然是汽车。

继承定义is-a关系,即如果您将汽车定义为继承自引擎,则表示 carengine 。更改引擎意味着改变汽车本身的类型 - 如果更改基类,它会自动更改派生类。使用合成时,此约束不存在。

所以在你的例子中,组合是正确的方法。

答案 2 :(得分:0)

对于纯合成,还可以进行运行时更改:

class Car {
private:
   CarPart &get_part(int i) const { 
        switch(i) {
            case 0: return e;
            case 1: return w1;
            case 2: return w2;
            case 3: return w3;
            case 4: return w4;
        }
   }
private:
   Engine e;
   Wheel w1, w2, w3, w4;
};

然后举例说明设置属性很简单:

void set_property(int id, std::string name, int value) {
    CarPart &p = get_part(id);
    p.set(name, value);
}

这就像你能得到的那样充满活力......