实现一个依赖于姐妹班级的课程

Joe*_*ont 0 c++ oop

比方说,我有两个派生自抽象基类的类Ingredient.现在,CarrotPotato实现纯虚函数(称之为Taste())的Ingredient通过公共继承.现在,假设我想有一类Salt就是一个Ingredient(即,它是由它派生的),但需要调用Taste()它的姊妹类的实现?

基本上,Salt该类稍微修改了Taste()其姐妹类的实现.这可以实施吗?如果是这样,怎么样?

这是我想要做的草图:

class Ingredient {
    virtual void Taste() = 0;
};

class Carrot : public Ingredient {
    void Taste() { printf("Tastes like carrot");}
};

class Potato : public Ingredient {
    void Taste() { printf("Tastes like potato"); }
};

class Salt : public Ingredient {
    void Taste() { SisterClass->Taste(); printf(" but salty"); }
};
Run Code Online (Sandbox Code Playgroud)

Que*_*tin 5

盐不能合理地提供改良的味道:它需要一种实际的其他成分来加盐.但是其他哪些成分呢?事实上,什么有"东西,但咸"的味道不是盐,而是含有另一种成分的咸制剂.这可以通过以下几种方式建模:

组成

该准备字面上包含其他成分,并代理呼叫.

class SaltedPreparation : public Ingredient {
    Ingredient *baseIngredient;
    void Taste() { baseIngredient->Taste(); printf(" but salty"); }
};
Run Code Online (Sandbox Code Playgroud)

Tomato tomato;
SaltedPreparation preparation;
preparation.baseIngredient = &tomato;
preparation.Taste();
Run Code Online (Sandbox Code Playgroud)

遗产

一个咸的番茄仍然是番茄,不是吗?这取决于与组合物相同的原理,但成分盐本身.我猜.

class SaltedTomato : public Tomato {
    void Taste() { Tomato::Taste(); printf(" but salty"); }
};
Run Code Online (Sandbox Code Playgroud)

SaltedTomato tomato;
tomato.Taste();
Run Code Online (Sandbox Code Playgroud)

混入

每次我需要调味时,我都不热衷于编写新课程,所以让我们为此编写一个模板!Mixin模式对于现有类的这种通用修改是典型的.

template <class BaseIngredient>
class Salted : public BaseIngredient {
    void Taste() { BaseIngredient::Taste(); printf(" but salty"); }
};
Run Code Online (Sandbox Code Playgroud)

Salted<Tomato> tomato;
tomato.Taste();
Run Code Online (Sandbox Code Playgroud)

综合

所有上述模型都失去了盐本身也应该成为一种成分的事实.这可能没问题,但如果必须怎么办?然后复合图案可能是有用的.我们也将调味料与主要成分区分开来,因为我们不喜欢咸咸盐.

class Seasoning : public Ingredient { };

class Salt : public Seasoning {
    void Taste() { printf("salty"); }
};

class SeasonedPreparation : public Ingredient {
    Ingredient *ingredient;
    Seasoning *seasoning;
    void Taste() { ingredient->Taste(); printf(", but "); seasoning->Taste(); }
};
Run Code Online (Sandbox Code Playgroud)

Tomato tomato;
Salt salt;
SeasonedPreparation preparation;
preparation.ingredient = &tomato;
preparation.seasoning = &salt;
preparation.Taste();
Run Code Online (Sandbox Code Playgroud)

我现在有点饿了.