c++对象创建相同类型的新实例

c++ Object creating new instances of same type

本文关键字:实例 新实例 对象 创建 同类型 c++      更新时间:2023-10-16

有没有一种方法可以让对象在不指定该类型的情况下创建自己类型的新对象?

class Foo {
public:
    virtual Foo* new_instance() {
        return new type_of(this); // Some magic here
    }
};
class Bar: public Foo {
};
Foo* a = new Foo();
Foo* b = new Bar();
Foo* c = a->new_instance();
Foo* d = b->new_instance();

我现在希望cFoo类型,而d应该是Bar类型。

简短的回答:不,没有办法让这种魔法发生。

您可以使用宏使覆盖子类中的函数变得更容易,或者创建一个使用"奇怪的重复模板模式"的中间类:

template <typename T>
class FooDerived : public Foo
{
public:
    T* new_instance() {
        return new T();
    }
};
class Bar : public FooDerived<Bar>
{
};
Foo* a = new Bar();
Foo* b = a->new_instance(); // b is of type Bar*

但这肯定不值得付出努力。

直接解决方案:

class Foo {
public:
    virtual Foo* new_instance() {
        return new Foo();
    }
};
class Bar: public Foo {
public:
    virtual Foo* new_instance() {
        return new Bar();
    }
};

您可以使用Mixin添加工厂类。对于工厂函数来说,这似乎相当复杂,当然更难理解。

#include <typeinfo>
#include <cassert>
#include <iostream>
template<class T> class WithFactory: public T {
public:
    WithFactory<T>* new_instance() override {
        return new WithFactory<T>( );
    }
};
class FactoryFunction {
    virtual FactoryFunction* new_instance() = 0;
};
class Foo_: public FactoryFunction {
public:
    virtual void f() {
        std::cout << "Foo" << std::endl;
    }
};
typedef WithFactory<Foo_> Foo;
class Bar_: public Foo {
public:
    virtual void f() override {
        std::cout << "Bar" << std::endl;
    }
};
typedef WithFactory<Bar_> Bar;
int main()
{
    Foo* a = new Foo();
    Foo* b = new Bar();
    Foo* c = a->new_instance();
    Foo* d = b->new_instance();
    assert( typeid(a) == typeid(c) );
    assert( typeid(b) == typeid(d) );
    a->f();
    b->f();
    c->f();
    d->f();
    return 0;
}

输出为

Foo
Bar
Foo
Bar

是的,你只需要做

virtual Foo* new_instance() { return new Foo(); }

然后在每个派生类中,您再次重载它以执行相同的操作(尽管我更喜欢模板方法而不是这种方法)