2017-11-11 298 views
0

你能給我一個提示,如何使這段代碼工作,因爲我想要它?我想derived_tDerived,但它總是Base動態多態類型扣除使用decltype

#include <iostream> 
#include <string> 
#include <memory> 

struct Base { 
    virtual std::string me() { return "Base"; } 
}; 

struct Derived : Base { 
    virtual std::string me() override { return "Derived"; } 
}; 

void foo(std::shared_ptr<Base> ptr) { 

    using derived_raw_t = decltype(*ptr); 
    using derived_t = std::remove_reference<derived_raw_t>::type; 

    derived_t* x = new derived_t(); 
    std::cout << x->me() << std::endl; 
} 

int main() { 

    std::shared_ptr<Base> ptr = std::make_shared<Base>(Derived()); 

    foo(ptr); 
} 
+1

'decltype'演繹靜態(編譯時)類型,這是'Base'在這種情況下。您可以將一個工廠虛擬函數添加到'Base'類中以生成該類的一個實例,並調用它來創建'x'調用'Derived'的工廠方法並創建一個Derived'類型的新實例。 – VTT

+0

爲什麼你需要'foo'中的派生類型?你想達到什麼目的? –

+0

你不能通過'decltype'來做到這一點,因爲這是一個編譯時設施。最好的辦法是在基類中重寫的基類中提供一個'virtual'函數'create()'來創建相應類型的對象。通常,需要一個副本,相應的函數名稱爲clone()。 –

回答

2

你的目標不明確從你的問題。無論如何,decltype(e)的行爲如預期,因爲它將返回編譯時已知的「e」的聲明類型。

使用decltype無法在運行時檢索派生類的實際類型。如果要根據多態對象的運行時類型「克隆」,可以使用virtualoverride。例如: -

struct Base { 
    // ... 
    virtual std::shared_ptr<Base> clone() { 
     return std::make_shared<Base>(*this); 
    } 
}; 

struct Derived : Base { 
    // ... 
    virtual std::shared_ptr<Base> clone() { 
     return std::make_shared<Derived>(*this); 
    } 
}; 

如果你想模仿協方差,請參閱:How To Make a clone method using shared_ptr and inheriting from enable_shared_from_this

+0

目標是使派生類中的克隆函數能夠返回指向派生的指針,而不是基指針。我可以用另一種方式知道我何時派生實例或基地?例如。 typeid()。name不知何故,但我不需要一個const char *類型,但類型本身 – banana36

+0

@ banana36:查看我最後發佈的鏈接,並改善你的問題與真正的目標。 –

+0

是的,鏈接幫助。謝謝。 – banana36