依赖于姐妹类的类的实现
Implementation of a class which depends on a sister class
我有多个,比如说2个,从抽象基类派生的类,比如Ingredient
。现在,Carrot
和Potato
通过公共继承实现了Ingredient
的纯虚拟函数(称为Taste()
)。现在,假设我想要一个类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"); }
};
盐本身无法合理地提供改良的味道:它需要一种真正的其他成分来盐。但其他成分是什么?事实上,有"有东西,但有咸味"的不是盐,而是一种咸味制剂,含有另一种成分。这可以通过以下几种方式进行建模:
组成
这种制剂实际上包含了其他成分,并代表了呼叫。
class SaltedPreparation : public Ingredient {
Ingredient *baseIngredient;
void Taste() { baseIngredient->Taste(); printf(" but salty"); }
};
Tomato tomato;
SaltedPreparation preparation;
preparation.baseIngredient = &tomato;
preparation.Taste();
继承
腌番茄还是番茄,不是吗?这取决于与成分相同的原理,但成分本身是盐。我想。
class SaltedTomato : public Tomato {
void Taste() { Tomato::Taste(); printf(" but salty"); }
};
SaltedTomato tomato;
tomato.Taste();
Mixin
我不喜欢每次需要调味时都写新课程,所以让我们为此写一个模板吧!Mixin模式是对现有类进行此类通用修改的典型模式。
template <class BaseIngredient>
class Salted : public BaseIngredient {
void Taste() { BaseIngredient::Taste(); printf(" but salty"); }
};
Salted<Tomato> tomato;
tomato.Taste();
复合材料
上述所有模型都忽略了盐本身也是一种成分的事实。这可能很好,但如果必须这样做怎么办?那么复合模式可能会很有用。让我们把调味料和主料区分开,因为我们不喜欢咸盐。
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(); }
};
Tomato tomato;
Salt salt;
SeasonedPreparation preparation;
preparation.ingredient = &tomato;
preparation.seasoning = &salt;
preparation.Taste();
我现在有点饿。
Salt
无法修改其他类的实现。但是Salt
可以被赋予一个指向另一个Ingredient
的指针来进行操作,例如:
class Salt : public Ingredient
{
private:
Ingredient *OtherIngredient;
public:
Salt(Ingredient *AOther) : OtherIngredient(AOther) {}
virtual void Taste() { OtherIngredient->Taste(); printf(" but salty"); }
};
然后你可以这样做:
Potato potato;
Salt salt(&potato);
salt.Taste();
但这真的没有道理,是吗?盐尝起来不像土豆,但土豆可以尝起来很咸。因此,我可能会采取不同的方法:
#include <vector>
class Ingredient
{
public:
virtual void Taste() = 0;
};
class Seasoning : public Ingredient
{
};
class SeasonableIngredient : public Ingredient
{
protected:
std::vector<Seasoning*> seasonings;
virtual void TastesLike() = 0;
public:
virtual void Taste()
{
printf("Tastes like ");
TastesLike();
if (!seasonings.empty())
{
std::vector<Seasoning*>::iterator iter = seasonings.begin();
printf(" but ");
iter->Taste();
++iter;
while (iter != seasonings.end())
{
printf(" and ");
iter->Taste();
++iter;
}
}
}
void AddSeasoning(Seasoning *seasoning) { seasonings.push_back(seasoning); }
};
class Carrot : public SeasonableIngredient
{
protected:
virtual void TastesLike() { printf("carrot"); }
};
class Potato : public SeasonableIngredient
{
protected:
virtual void TastesLike() { printf("potato"); }
};
class Salt : public Seasoning
{
public:
void Taste() { printf("salty"); }
};
class Pepper : public Seasoning
{
public:
void Taste() { printf("peppery"); }
};
Potato potato;
Salt salt;
Pepper pepper;
Potato.AddSeasoning(&salt);
Potato.AddSeasoning(&pepper);
potato.Taste();
相关文章:
- 如果没有malloc,链表实现将失败
- 如何在c++中实现处理器调度模拟器
- 如何在c++中使用引用实现类似python的行为
- 实现无开销push_back的最佳方法是什么
- 使用简单类型列表实现的指数编译时间.为什么
- 如何在BST的这个简单递归实现中消除警告
- 实现一个在集合上迭代的模板函数
- 我应该实现右值推送功能吗?我应该使用std::move吗
- 如何正确实现和访问运算符的各种自定义枚举器
- C++Union/Struct位域的实现和可移植性
- 这个极客对极客的trie实现是否存在内存泄漏问题
- 在c++中实现LinkedList时,应出现未处理的错误
- 为左值和右值的包装器实现C++范围
- 使用模板进行堆栈实现; "name followed by :: must be a class or namespace"
- 使用GSoap实现ONVIF
- 在用于格式4的arm模拟器中实现功能时的一个问题
- 用于AVX的ln(x)的实现,m256
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 在C++中,如何在类和函数(可能是模板化的)的头中编写完整的实现
- 依赖于姐妹类的类的实现