2014-04-10 90 views
1

有沒有辦法讓對象有可能創建它自己類型的新對象,而不指定這種類型?C++對象創建相同類型的新實例

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型的,而dBar型。

+1

你試圖定義一個單/工廠? – Shoe

+0

不是一個單身人士。我不確定是否可以使用工廠解決問題? –

回答

5

簡答:不,沒有辦法讓這種奇蹟發生。

你可以使用宏來使重寫功能在子類中比較容易,或創建一個使用「奇異遞歸模板模式」的中間階段:

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* 

但是,這肯定是不值得的。

+0

但是當我想添加一個新的子類酒吧稍後,我將不得不使Bar成爲模板課程。這將會破壞客戶。 – Jens

+0

不,您不必爲了同樣的原因將Bar製作爲模板Foo不是模板。如果你真的想這樣做(但你爲什麼?!!),你可以讓'FooDerived'帶兩個參數:'template class FooDerived:public Base'。然後你可以做'班級Buzz:public FooDerived '。 –

+0

好吧,同樣的說法:當我想要引入一個從Bar派生的新類Buzz時會發生什麼? – Jens

0

是的,你只是在用它做

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

然後在每個派生類中過載再次做同樣的(雖然我更喜歡模板的方法來這樣的事情)

+2

創建它自己的類型**的新對象,而不指定此類型**? – dasblinkenlight

+0

我不相信C++,如果您使用模板系統爲您生成該代碼,您可以將這樣的東西關閉(因爲您不必輸入它),否則就不會。 – Entropy

1

直截了當的解決方案:

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

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

是的,但問題是,是否有一個(非直接的)解決方案,讓我這樣做**沒有指定類型**,因此沒有在每個派生類中重載 –

1

您可以使用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 
相關問題