[英]How to design a flexible C++ program in which derived classes interact?
我希望這里的專家對以下問題有意見。 我想設計一個程序,其中來自不同基類的派生類彼此交互。 為了闡明我的觀點,我構建了一個示例。
想象一下我試圖去動物園。 在這個動物園里,我們有動物,有水果,這是我的基礎課。 只有在運行時,我們才能知道我們擁有哪些動物以及哪些果實。 假設我有一只猴子和一根香蕉。
如何讓這只猴子以優雅的方式食用香蕉,而吃香蕉只是這只猴子的一項非常獨特的技能? 請注意,我不需要通用的eat函數,因為在設計中我需要完全自由地實現派生動物可以執行的動作。
這是隨附的示例:
#include <string>
#include <iostream>
class cfruit
{
};
class cbanana : public cfruit
{
};
class canimal
{
};
class cmonkey : public canimal
{
public:
int eatbanana(cbanana *) { std::cout << "BURP" << std::endl; }
};
int main()
{
cfruit *fruit;
canimal *animal;
// on runtime the animal and the fruit is decided, so we have to
// initialize it on the base pointer
// assume we get a monkey and a banana
fruit = new cbanana();
animal = new cmonkey();
// now, we would like our monkey to eat a banana, which we cannot do...
// UNLESS... we do something really UGLY
static_cast<cmonkey *>(animal)->eatbanana(static_cast<cbanana *>(fruit));
return 0;
}
您在問我們一種“優雅地”違反李斯科夫原則的方法。
當你操縱媽媽級,你不應該認為是背后實例化具體的派生類。
這稱為不良設計,編碼有異味。
如果您的班級確實是猴子,並且您想讓它吃香蕉:那么您不應該像猴子那樣操縱它。
無論如何,尋找解決方案的途徑可以從這種方式開始:正如您所解釋的,動物及其果實之間存在隱式鏈接。 您可以創建一個班餐,其目標是明確管理此鏈接。
struct Meal
{
virtual void consume() = 0;
}
Meal* factoryCookMonkeyMeal(Monkey& monkey, Banana& banana)
{
return new MealMonkey(monkey,banana);
}
struct MealMonkey : public Meal
{
Monkey& monkey;
Banana& banana;
virtual void consume(){ monkey.eat_banana(banana);};
}
Meal* factoryCookBirdMeal(Bird& bird, Cherry& cherry)
{
return new MealBird(bird,cherry);
}
struct MealBird : public Meal
{
Bird& bird;
Cherry& cherry;
virtual void consume(){ bird.eat_cherry(cherry);};
}
但是,您不能准確地告訴我們確定動物和水果的方式...所以這無濟於事...因為正是這種選擇知道了調用好的factoryMethod所必須使用的信息,從而創建了適當的一餐。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.