来自思考C ++ Vol。 1 (P-33):
组合具有很大的灵活性。会员 你的新课程的对象通常是私人的,制作它们 使用该类的客户端程序员无法访问。这个 允许您在不打扰现有成员的情况下更改这些成员 客户代码。
您还可以在运行时将成员对象更改为 动态更改程序的行为。遗产, 接下来描述的,因为没有这种灵活性 编译器必须对创建的类放置编译时限制 继承。
如何在合成中更改运行时的成员对象?
Aren在写入类声明时包含的对象是什么?
class car
{
private:
engine obj;
}
因此,类car
包含类engine
的对象。我们如何在运行时更改它?
或者我错过了一些观点?
答案 0 :(得分:6)
尝试使用指向成员对象的指针:
class car {
engine *obj;
}
现在,您可以在运行时选择是否使用rotary_engine
或v8_engine
或flux_capacitor_engine
的实例。
当然,您可能希望使用类似unique_ptr
或shared_ptr
的内容来管理成员对象的所有权和生命周期。
答案 1 :(得分:1)
这确实是一个模糊的陈述。
组合定义了has-a
关系,即 car
有engine
。您可以更换汽车的引擎,汽车仍然是汽车。
继承定义is-a
关系,即如果您将汽车定义为继承自引擎,则表示 car
为engine
。更改引擎意味着改变汽车本身的类型 - 如果更改基类,它会自动更改派生类。使用合成时,此约束不存在。
所以在你的例子中,组合是正确的方法。
答案 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);
}
这就像你能得到的那样充满活力......