关于c ++:基于现有实例创建类的新实例

Creating a new instance of the class based on the existing instance

我有许多代表不同种类动物的课程。这个想法是,如果同一物种的两个动物相遇,那么这个物种的新动物应该被创造出来——这意味着我想在这种情况下创造一个特定类别的新的存在。如果熊会相遇,我想创造新的熊实例,当蝙蝠相遇时,新的蝙蝠实例。

如何在不复制代码的情况下实现这一目标?我想避免使每个班级(动物)的个人条件。我正在寻找一个解决方案,在这个解决方案中,将根据现有实例的类自动创建类的新实例。


因为您知道两个父对象必须具有相同的类型,所以您不需要通常的双调度解决方案——这些解决方案是为了处理所有可能的组合。

让我们只使用克隆模式的一个稍微修改过的变体。基类Animal获得纯虚拟克隆函数:

1
2
3
struct Animal {
    virtual std::unique_ptr<Animal> mateWith(Animal const &other) const = 0;
};

然后,每个子类实现这个方法,通过rtti检查其他Animal实际上是正确的类型:

1
2
3
4
5
6
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);
    }
};

如果另一只动物不是熊的话,这会把它扔出去。您还可以用其他一些错误处理来替换它:

1
2
3
4
5
6
7
8
9
10
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
2
3
4
#include <typeinfo>

if ( typeid(YourClass1) == typeid(YourClass2) )
// do something

要创建一个新实例,请将一个纯虚拟克隆添加到您的基类中,然后在每个动物中实现它。

还可以向基类添加一个名称字段,并与之进行比较。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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() );
  ...
}