C ++错误:无法使用type值初始化类型的引用(C++ error: A reference of type cannot be initialized with a value of type)

编程入门 行业动态 更新时间:2024-10-27 17:15:46
C ++错误:无法使用type值初始化类型的引用(C++ error: A reference of type cannot be initialized with a value of type)

嗨,我遇到了一个问题,我无法找到解决方案。 我正在创建一个带有智能指针的实体组件系统。

我得到的错误是:

类型为std::unique_ptr<PrimaryComponent, std::default_delete<PrimaryComponent>> & (非const-qualified)的引用无法使用std::unique_ptr<PlayerGraphics, std::default_delete<PlayerGraphics>>类型的值进行初始化std::unique_ptr<PlayerGraphics, std::default_delete<PlayerGraphics>>

游戏世界类:

auto GameWorld::Setup_World() -> void { player->Attach_Component(player_Graphics); Add_GameObject(player); }

gameobject类附加组件功能:

void GameObject::Attach_Component(std::unique_ptr<PrimaryComponent> &component) { if (component != nullptr) { component_container.push_back(component); } }

player_Graphics和玩家的声明:

class GameWorld { private: std::vector<std::unique_ptr<GameObject>> gameObject_List; std::unique_ptr<GameObject> player; std::unique_ptr<PlayerGraphics> player_Graphics

player是player_Graphics , player_Graphics是一个派生自PrimaryComponent的图形组件。

主要组件类:

class PrimaryComponent { protected: public: PrimaryComponent(); virtual ~PrimaryComponent(); virtual void Render(GameObject &gameObject) = 0; virtual void Update(GameObject &gameObject, GameWorld &gameWorld, float gameTime) = 0; };

PlayerGraphics类:

class PlayerGraphics : public GraphicsComponent { public: PlayerGraphics(); virtual ~PlayerGraphics(); virtual void Render(GameObject &gameObject); virtual void Update(GameObject &gameObject, GameWorld &gameWorld, float gameTime); };

PlayerGraphics派生自GraphicsComponent,它源自PrimaryComponent。

Hi I got a problem I can't find a solution to. I'm creating a entity - component system with smart pointers.

The error I get is:

a reference of type std::unique_ptr<PrimaryComponent, std::default_delete<PrimaryComponent>> & (not const-qualified) cannot be initialized with a value of type std::unique_ptr<PlayerGraphics, std::default_delete<PlayerGraphics>>

The gameworld class:

auto GameWorld::Setup_World() -> void { player->Attach_Component(player_Graphics); Add_GameObject(player); }

The gameobject class attach component function:

void GameObject::Attach_Component(std::unique_ptr<PrimaryComponent> &component) { if (component != nullptr) { component_container.push_back(component); } }

The declaration of player_Graphics and player:

class GameWorld { private: std::vector<std::unique_ptr<GameObject>> gameObject_List; std::unique_ptr<GameObject> player; std::unique_ptr<PlayerGraphics> player_Graphics

player is a GameObject, player_Graphics is a Graphics Component which derives from PrimaryComponent.

The primary component class:

class PrimaryComponent { protected: public: PrimaryComponent(); virtual ~PrimaryComponent(); virtual void Render(GameObject &gameObject) = 0; virtual void Update(GameObject &gameObject, GameWorld &gameWorld, float gameTime) = 0; };

The PlayerGraphics class:

class PlayerGraphics : public GraphicsComponent { public: PlayerGraphics(); virtual ~PlayerGraphics(); virtual void Render(GameObject &gameObject); virtual void Update(GameObject &gameObject, GameWorld &gameWorld, float gameTime); };

PlayerGraphics derives from GraphicsComponent which derives from PrimaryComponent.

最满意答案

问题在于参考:

这条线:

void GameObject::Attach_Component(std::unique_ptr<PrimaryComponent> &component)

应该:

void GameObject::Attach_Component(std::unique_ptr<PrimaryComponent> component)

然后,当你打电话给它时,而不是:

player->Attach_Component(player_Graphics);

你应该做:

player->Attach_Component(std::move(player_Graphics));

也就是说,该函数应该取得指针的所有权。 请注意,原始的player_Graphics将被设置为null(如果您想保留该对象的引用,那么您将其移入,那么您使用的是错误的工具)。

您可能想知道为什么在您的代码中传递std::unique_ptr<PrimaryComponent>直接起作用,但传递std::unique_ptr<PlayerGraphics>则不然。 那么解释是你使用的是非const引用,而非const引用只能绑定到完全相同的对象。 但是,如果您按值传递参数,那么智能指针将被移动,它将全部起作用。

这一切都有道理, std::unique_ptr意味着是不可复制的,不可共享的,可移动的智能指针。 您应该移动指针,而不是通过引用传递它。

TL; DR:如果B是A的子类,您可以将std::unique_ptr<B>到std::unique_ptr<A>但是不能将std::unique_ptr<B>绑定到std::unique_ptr<B>类型的引用std::unique_ptr<a>& 。

PS。 移动和强制转换的构造函数声明如下:

template <class T, class D = default_delete<T>> class unique_ptr { template <class U, class E> unique_ptr (unique_ptr<U,E>&& x) noexcept; };

The problem is in the reference:

The line:

void GameObject::Attach_Component(std::unique_ptr<PrimaryComponent> &component)

should be:

void GameObject::Attach_Component(std::unique_ptr<PrimaryComponent> component)

And then, when you call it, instead of:

player->Attach_Component(player_Graphics);

you should do:

player->Attach_Component(std::move(player_Graphics));

That is, the function should take ownership of the pointer. Note that the original player_Graphics will be set to null (you moved it in, if you want to keep a reference ot that object then you are using the wrong tool).

You may be wondering why in your code passing a std::unique_ptr<PrimaryComponent> directly works, but passing a std::unique_ptr<PlayerGraphics> does not. Well the explanation is that you are using a non-const reference, and non-const references can only bind to an object of the exact same time. However if you pass the argument by value, then the smart pointer will be moved and it all will just work.

This all makes sense, std::unique_ptr is meant to be non-copyable, non-shareable, moveable smart pointers. You are expected to move the pointer around, not to pass it by reference.

TL;DR: If B is a subclass of A you can move a std::unique_ptr<B> into a std::unique_ptr<A> but you cannot bind a std::unique_ptr<B> to a reference of type std::unique_ptr<a>&.

PS. The constructor to move&cast is declared as follows:

template <class T, class D = default_delete<T>> class unique_ptr { template <class U, class E> unique_ptr (unique_ptr<U,E>&& x) noexcept; };

更多推荐

本文发布于:2023-07-24 20:58:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1251036.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:初始化   错误   类型   type   initialized

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!