2017-02-27 33 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

感谢您为我清理这个,现在它是有道理的! –

相关问题