我有一個基類,它包含一個成員變量std :: unique_ptr < Base> next。我有幾個派生類的基地。實例化多態成員變量是合適的類型
我有一個非虛函數Base :: grow(),接下來要初始化。接下來將總是指向調用對象類型的對象增長。
接下來是正確的類型,通過Base :: grow()內的虛函數調用來保證。
爲每個派生類創建一個虛擬函數很麻煩並且容易出錯,因此我的問題是:我可以更簡單地做到這一點嗎?
我目前的工作極少例子是這樣的:
#include <iostream>
#include <memory>
class Base{
public:
static const unsigned SIZE = 3;
std::unique_ptr<Base> next;
void grow(unsigned index){
if (index < SIZE){
print();
next = get_new();
next.get()->grow(index + 1);
}
}
virtual std::unique_ptr<Base> get_new(){
return std::unique_ptr<Base>(new Base());
//return std::move(std::unique_ptr<Base>(new Base())); (move not nec. see comments)
}
virtual void print(){
std::cout << "a Base ";
}
};
class Derived: public Base{
public:
virtual void print(){
std::cout << "a Derived ";
}
virtual std::unique_ptr<Base> get_new(){
return std::unique_ptr<Base>(new Derived());
}
};
int main(){
std::unique_ptr<Base> b;
b = std::unique_ptr<Base> (new Base());
b->grow(0);
std::unique_ptr<Base> c;
c = std::unique_ptr<Base> (new Derived());
c->grow(0);
}
輸出是正確的:一個基地一個基地一個基地一個導出的導出派生
總結:我想一個解決方案,消除繁瑣的get_new,我希望Base :: grow根據調用對象的類型確定要創建的類型。我考慮過使用decltype,但沒有成功。
代碼段與嘗試在運行時確定類型:以上
typedef std::remove_reference<decltype(*this)>::type DynamicBase;
next = std::unique_ptr<DynamicBase>(new DynamicBase());
DYNAMICBASE總是確定爲基地,即使this
是指向派生
C++沒有一個可靠的方法來獲得「通話對象」的類型在運行時(除非「調用對象」你的意思是'this' - - 你可以通過RTTI獲得有限的*信息),即使這樣你也需要一些反射能力來創建一個新類型的對象。總之,沒有答案滿足您的具體要求,因爲它不能在C++中完成。如果你對他們開放,可能會有其他選擇。 – cdhowie
你不需要'移動'std :: unique_ptr (新的Base())'表達式,它已經是一個右值。 –
aschepler
@cdhowie我認爲這個評論應該是一個答案。 – Walter