gpt4 book ai didi

c++ - 必要时违反继承之上的组合可以吗?

转载 作者:行者123 更新时间:2023-11-30 01:34:46 25 4
gpt4 key购买 nike

我有一组类:


// This is #included from another header file
// I don't want to inherit this, because it ain't my code
class DrawableObject;

class Animal {
DrawableObject obj;
// Does not define run() or swim()
};

class Cat : public Animal {
void run() { /* Calls obj.setPosition() and other stuff */ }
};

class Dog : public Animal {
void run() { /* Calls obj.setPosition() and other stuff */ }
void swim() { /* Calls obj.setPosition() and other stuff */ }
};

class Dolphin : public Animal {
void swim() { /* Calls obj.setPosition() and other stuff */ }
};

这里,Dog::r​​un()Cat::run() 碰巧使用了完全相同的代码,而 Dog::swim() Dolphin::swim() 也使用相同的代码。我不想到处复制粘贴代码,而是想重用它。明智的解决方案似乎是在基类 (Animal) 和具体类 (Cat/Dog/Dolphin) 之间添加中间子类:

       /-> RunnableAnimal --> Cat
| \
Animal-| |-> Dog
| /
\-> SwimmableAnimal -> Dolphin

问题是:我是否违反了“组合优于继承”的规则?如果是这样,这是否非常好,或者是否有一种方法可以在实现代码重用的同时遵守 CoI?

注意:我需要或想要多态——当我使用run()时,我总是使用具体的(Cat/Dog/Sloth) 类,而不是基础 Animal 类。

最佳答案

更好的继承模式:

          /–––––––––– Cat
/ /
/ Runner
/ \
Animal –––––––––––––– Dog
\ /
\ Swimmer
\ \
\–––––––––– Dolphin

您可以避免使用您的方法引入的菱形模式。

您可以不继承,而是在需要的地方聚合动物中的 Runner/Swimmer 实例,让动物的功能只委托(delegate)给成员。

关于你的模型只是一个小问题:它并没有真正反射(reflect)现实,实际上,猫虽然不喜欢水,但也是很好的游泳运动员......

编辑:作为RunnerSwimmer 需要访问Animal 的成员:您可以通过以下方式提供curiously recurring template pattern ;在下面添加了一个演示:

class Animal
{
protected:
int n = 7;
};

template <typename T>
class Swimmer
{
public:
void swim()
{
std::cout << static_cast<T*>(this)->n << std::endl;
}
};

class Dolphin : public Animal, public Swimmer<Dolphin>
{
friend class Swimmer; // n is protected!
// (alternatively, Swimmer might already be a friend of Animal)
};


int main(int argc, char* argv[])
{
Dolphin d;
d.swim();

return 0;
}

关于c++ - 必要时违反继承之上的组合可以吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55670729/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com