【问题标题】:Proper Design to Avoid Use of Dynamic_Cast避免使用 Dynamic_Cast 的正确设计
【发布时间】:2017-06-29 21:37:05
【问题描述】:

我遇到的问题与此处提出的问题非常相似: Using derived methods that aren't in the base class

在那个问题中,IdeaHat 提供的最佳答案是使用 dynamic_cast,但他/她接着说,如果你不得不求助于它,那么你的设计就是糟糕的。我注意到其他问题的答案非常相似。

那么,在这种情况下,正确的设计是什么?

为了便于讨论,我们使用以下代码:

enum AnimalType {
    dog = 0,
    cat
}

Class Animal {
    virtual AnimalType getType() = 0;

    void eat() {
        cout << "Ate some food!" << endl;
    }

    void sleep() {
        cout << "Zzzz..." << endl;
    }
};

Class Dog : public Animal {
    AnimalType getType() {
        return AnimalType::dog;
    }

    void fetch() {
        cout << "Fetched the stick!" << endl;
    }
};

Class Cat : public Animal {
    AnimalType getType() {
        return AnimalType::cat;
    }
};

//A factory function
Animal* shelter(AnimalType type) {
    if(type == AnimalType::dog) {
        return new Dog;
    }
    else {
        return new Cat;
    }

int main() {
    Animal* pet = shelter(AnimalType::dog);

    pet->fetch();
}

基本上,我有一家工厂生产特定类的多个子类。一些子类包含父/其他子类中不存在的函数,这将阻止在没有解决方法的情况下使用多态性。

我将如何以一种可行的方式实现这一点,并且也被认为是“好的设计”?

【问题讨论】:

  • 深入了解。问问自己,你做了什么让自己处于 A) 你有一个通用的Animal 和 B) 你需要向fetch 提问。 A 或 B 都错了,你只能通过看你的整体设计来知道哪一个,而不是一堆随机的动物测试类。
  • 您可以查看visitor Pattern,然后有一个访问者供您使用,除了会抓取的狗之外什么都不做。
  • @Jarod42,这看起来很有可能;我必须更仔细地调查。
  • @Nicol Bolas,我不确定为什么这些是互斥的。如果我理解你的意思,你是说如果我想让我的 Dog 获取(),我不应该从 Animal 继承?
  • @AndrewKline:“我不知道为什么它们是互斥的。”因为不是所有的Animals 都可以fetch;这就是Animal 没有fetch 函数的意思。如果你向函数传递一个Animal 对象,那么它应该只做所有Animal 对象都可以做的事情。如果该函数需要生成它传递的fetch,那么它传递的不应该是Animal。所以这归结为你是如何让自己陷入如此矛盾的境地的问题。而你的例子并没有表明这一点;太人工了。

标签: c++ inheritance polymorphism


【解决方案1】:

简单:

void functionTakingAnimal(Animal& a) {
    a.eat();
    a.sleep();
}

int main() {
    Dog pet;
    pet.fetch();
    functionTakingAnimal(pet);
}

不要在需要之前提前销毁静态类型信息。

【讨论】:

  • 我不清楚这对我有什么帮助。如果我从收容所()中得到一个动物,我怎么知道它是否可以获取?
  • @AndrewKline 如果您需要可以fetch() 的东西,那么不要从可能给您无法fetch() 的东西的来源获取它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-03
  • 2010-10-02
  • 1970-01-01
  • 2022-10-04
相关资源
最近更新 更多