我有许多代表不同种类动物的课程。这个想法是,如果同一物种的两只动物相遇,那么应该创造这个物种的新动物 - 这意味着我想在这种情况下创造一个特定类别的新动物。如果熊会遇到我想要创建熊的新实例,当蝙蝠遇到新的蝙蝠实例时。
如何在不重复代码的情况下实现这一目标?我想避免为每个班级(动物)制作个人条件。我正在寻找能够根据现有实例的类自动创建类的新实例的解决方案。
答案 0 :(得分:2)
由于您知道父对象必须具有相同的类型,因此您不需要通常的双调度解决方案 - 这些解决方案可用于处理所有可能的组合。
让我们使用一个稍微修改过的Clone模式变体。基类Animal
获得纯虚拟克隆函数:
struct Animal {
virtual std::unique_ptr<Animal> mateWith(Animal const &other) const = 0;
};
然后,每个子类都实现此方法,通过RTTI检查另一个Animal
实际上是正确的类型:
struct Bear : Animal {
std::unique_ptr<Animal> mateWith(Animal const &other) const override {
auto &otherBear = dynamic_cast<Bear const &>(other);
return std::make_unique<Bear>(*this, otherBear);
}
};
如果另一只动物不是熊,这将抛出std::bad_cast
。您也可以将其替换为其他一些错误处理:
struct Bear : Animal {
std::unique_ptr<Animal> mateWith(Animal const &other) const override {
auto *otherBear = dynamic_cast<Bear const *>(&other);
if(!otherBear) {
// This is not a bear!
}
return std::make_unique<Bear>(*this, *otherBear);
}
};
答案 1 :(得分:1)
您可以使用以下方法比较这些类型:
#include <typeinfo>
if ( typeid(YourClass1) == typeid(YourClass2) )
// do something
要创建新实例,请将纯虚拟克隆添加到Base类,然后在每个动物中实现它。
您还可以向Base类添加名称字段,并与之进行比较。
class Animal{
public:
virtual shared_ptr<Animal> clone() = 0;
virtual const string & getname() = 0;
};
class Bear: public Animal{
public:
virtual shared_ptr<Animal> clone()
{
return shared_ptr<Animal>(new Bear());
}
virtual const string & getname()
{
return "bear";
}
};
int main(int argc, const char * argv[])
{
Bear b1;
Bear b2;
shared_ptr<Animal> b3;
if ( b2.getname() == b2.getname() )
b3 = ( b1.clone() );
...
}