3

来自C++ 中的思考卷。1(P-33):

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

我们如何在组合运行时更改成员对象?
写类声明的时候不包括对象吗?

class car
{
private:
engine obj;
}

所以,这里的类car包含类的对象engine。我们如何在运行时改变它?

还是我错过了一些观点?

4

3 回答 3

7

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

class car {
    engine *obj;
}

现在您可以在运行时选择是否使用rotary_engineorv8_engine或的实例flux_capacitor_engine

当然,您可能希望使用 aunique_ptr或 a之类的东西shared_ptr来管理成员对象的所有权和生命周期。

于 2012-12-16T07:21:46.010 回答
1

这确实是一个有点模糊的说法。

组合定义了一种has-a关系,即carhasengine。您可以更换汽车的发动机,汽车仍然是汽车。

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

因此,在您的示例组合中是正确的方法。

于 2012-12-16T07:27:21.620 回答
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);
}

这是尽可能动态的......

于 2012-12-16T09:21:41.277 回答