gpt4 book ai didi

c++ - 鸟类、蜜蜂和抽象类

转载 作者:太空狗 更新时间:2023-10-29 20:23:32 24 4
gpt4 key购买 nike

新手我目前被这个看似简单的问题所困扰。假设我想写一些关于一群动物从此幸福地繁殖的代码。显然,它们都需要一个 mate() 方法,所以我可以像这样定义一个抽象类:

class FemaleAnimal {
public:
virtual FemaleAnimal mate(const MaleAnimal& a) const = 0;
virtual MaleAnimal mate(const MaleAnimal& a) const = 0;
}

并导出所有不同的物种:

class FemaleBird : public FemaleAnimal {
public:
FemaleBird mate (const MaleBird& b) const;
MaleBird mate (const MaleBird& b) const;
}

class FemaleBee: public FemaleAnimal {
public:
FemaleBee mate (const MaleBee& b) const;
MaleBee mate (const MaleBee& b) const;
}

在main()中,我想要两个 vector

males = vector<MaleAnimal>
females = vector<FemaleAnimal>

其中每一个都可能包含鸟类和蜜蜂,并在运行时被填充。每个索引的物种匹配,所以如果 males[i] 是一只蜜蜂,那么 females[i] 也是一只蜜蜂,所以我可以这样做

vector<FemaleAnimal> femaleOffspring;
vector<MaleAnimal> maleOffspring;
for (int i=0; i<males.size(); ++i){
femaleOffspring.push_back( females[i].mate(males[i]) );
maleOffspring.push_back( females[i].mate(males[i]) );
}

现在,显然我希望派生类中的 mate() 方法实现基类中的方法,但是我必须为一般动物定义 mate(),例如

FemaleBee::mate(const MaleAnimal& a) const;

但是蜜蜂不与鸟类交配。我将如何实现这种特化?这有一些特殊的设计模式吗?我曾尝试研究协方差之类的东西,但这比帮助更令人困惑。

奖励问题:当 males[i] 和 females[i] 在运行时属于不同物种时,我如何捕获这种情况?

编辑:假设男性和女性来自完全不同的类层次结构,并且不能合理地派生自共同的基类。

编辑:为了完整起见,这里是基于 n.m. 的回答的最终解决方案。非常感谢大家!

#include <iostream>

using namespace std;

class GenericMale {
public:
virtual void test() = 0; // just to make the class abstract
};


template <typename Species>
class Male : public GenericMale
{
void test() {};
};


class GenericFemale {
virtual void tryMate (const GenericMale&) const = 0;
};


template <typename Species>
class Female : public GenericFemale
{
public:
virtual void tryMate (const GenericMale& m) const
{
try {
auto& p= dynamic_cast<const Male<Species>&>(m); // will throw if Species does not match
Species::doMate(p);
} catch ( exception& e) {
cerr << "[MATING ERROR] You filthy animals, stay within your own species!" << endl;
}
}
};


class Bee {
public:
static void doMate(const Male<Bee>& p) {
cout << "Buzz buzz buzz!" <<endl;
}
};


class Bird {
public:
static void doMate(const Male<Bird>& p) {
cout << "Chirpy chirpy cheep cheep!" << endl;
}
};



int main() {
Female<Bee> queenBee;
Male<Bee> drone;
queenBee.tryMate(drone);

Female<Bird> mamaBird;
Male<Bird> papaBird;
mamaBird.tryMate(papaBird);

queenBee.tryMate(papaBird);
}

最佳答案

您基本上有两个选择:编译时检查和运行时检查。

编译时

您的 MaleAnimalFemaleAnimal 对象没有带有您提供的签名的 mate 方法。事实上,由于任何雌性不能与任何雄性交配,方法签名

FemaleAnimal::mate(const MaleAnimal& a) const

是一个过于慷慨的 promise 。不要 promise 你无法实现的事情。

FemaleAnimal 应该能够与同一物种的 MaleAnimal 交配。我们怎么写下来?我们将物种编码为动物的类型。在 C++ 中,这将是一个模板。

template <typename Species>
class Animal ...

template <typename Species>
class MaleAnimal : public Animal<Species> ...

template <typename Species>
class FemaleAnimal : public Animal<Species>
{ ...
void mate (const MaleAnimal<Species>&) const ...
}

这种类型安全是有代价的。您不能将不同物种的代表放在同一容器中并保留它们的物种信息。每个物种都需要一个不同类型的单独容器。

 class AnimalContainer
{ ...
virtual void mateAll() = 0;
};

template <typename Species>
class SpecificContainer : public Container
{
...
std::vector<MaleAnimal<Species>> males;
std::vector<FemaleAnimal<Species>> females;
void mateAll()
{
for (...) females[i].mate(males[i]);
}
}

现在您可以保存一个包含 AnimalContainer 的容器,每个容器可以保存一个单独的物种。

运行时

您的 FemaleAnimal 可以尝试与任何 MaleAnimal 交配。尝试可能会失败。这最好用 dynamic_cast 建模:如果检查通过,它返回正确的类型,如果没有,它失败(抛出异常)。

层次结构可以这样修改:

class Animal ...

class GenericMaleAnimal : public Animal ...
class GenericFemaleAnimal : public Animal
{ ...
virtual void tryMate (const GenericMaleAnimal&) const = 0;
};

template <typename Species>
class MaleAnimal : public GenericMaleAnimal ...

template <typename Species>
class FemaleAnimal : public GenericFemaleAnimal
{ ...
virtual void tryMate (const GenericMaleAnimal& m) const
{
// will throw if species don't match
auto& other = dynamic_cast<const MaleAnimal<Species>&>(m);
// Specific mate procedure for given species
Species::doMate(*this, other);
}
};

现在您可以将所有内容保存在同一个容器中,并且您有责任使类型匹配。

关于c++ - 鸟类、蜜蜂和抽象类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32766402/

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