2017-02-27 34 views
1

好吧,爲了說明我遇到的問題,我將顯示一些(僞)代碼。無法返回包含派生指針的向量

可以說我有以下型號:

class Animal : public GameObject; 

class Player : public GameObject; 

class GameObject : public ObjectInterface; 

class ObjectInterface 
{ 
public: 
    virtual ~ObjectInterface() = default; 
    virtual vec3 GetPosition() = 0; 
} 

現在我還保存一些「對象上下文」,它擁有一定的遊戲對象的集合。

class ContextObject 
{ 
    // they implement ObjectInterface 
    vector<shared_ptr<Animal>> animals; 
    vector<shared_ptr<Player>> players; 
} 

現在我有一個TargetSelector類,它只有在ObjectInterface直接作用。

class TargetSelector 
{ 
    // this is somehow not possible, although `animals` are a subclass of `ObjectInterface` 
    vector<shared_ptr<Model::ObjectInterface>>& GetAvailableTargets() 
    { 
     return context->animals; // context is some `ObjectContext` 
    } 
} 

我希望上面的代碼工作,因爲一個Animal是類型ObjectInterface的。但相反,我得到一個錯誤,說它不能從vector<shared_ptr<Animal>>轉換爲vector<shared_ptr<ObjectInterface>>。這甚至假設工作?

有人可以解釋我爲什麼我不能做這種多態性,如果可能的話,一個很好的解決方案,所以我可以做到這一點。

謝謝,任何幫助表示讚賞!

+1

'shared_ptr '和'shared_ptr '是不同的類型。您可以將一個轉換爲另一個,但不能將它們別名。如果你想創建一個'vector >',你需要填寫'shared_ptr '等副本。 –

+3

也許你應該在所有情況下都存儲'shared_ptr ',動物'如果需要可以投入使用 –

回答

1

我期望上面的代碼工作,因爲AnimalObjectInterface類型。

不幸的是,類模板不能這樣工作。

鑑於

struct Base {}; 
struct Derived : Base {}; 

Derived d; 
Base& bref = d; // OK. 
Base b = d; // OK. 

然而,鑑於

template <tpename T> Foo {}; 

Foo<Derived> d; 
Foo<Base>& bref = d; // Not OK 
Foo<Base> b = d;  // Not OK. 

Derived是一種分型Base並不意味着Foo<Derived>是子類型的Foo<Base>

這個比喻也適用於shared_ptr。你的問題是通過使用另一層類模板來實現的。 shared_ptr<Derived>不是shared_ptr<Base>的子類型。沒關係當vector<shared_ptr<Base>>預警時能夠使用vector<shared_ptr<Derived>>

您可以在所有地方使用vector<shared_ptr<ObjectInterface>>,並確保在使用前將其轉換爲相應的shared_ptr類型。

查看http://en.cppreference.com/w/cpp/memory/shared_ptr/pointer_cast的各種pointer_cast功能。

+0

感謝您爲我清理這個,現在它是有道理的! –

相關問題