【问题标题】:How to use template inheritance and components如何使用模板继承和组件
【发布时间】:2019-11-03 10:14:37
【问题描述】:

我正在尝试将组件模式与模板一起使用:

template <typename ComponentGraphics>
struct Object {

    ComponentGraphics* graphics;
    // there is other components as well

    Object(ComponentGraphics* _graphics) : graphics(_graphics) {};

    void update() {
        graphics->update(this); //Error occure there
    };
};

然后我用一个 Player 类继承它:

class Player : public Object<PlayerGraphics> {
    using Object::Object;
public:

    sf::Vector2f position;
};

使用 PlayerGraphics.h:

class Player;
class PlayerGraphics{
public:
    void update(Player* parent);
};

PlayerGraphics.cpp:

#include "Player.h"

void PlayerGraphics::update(Player* parent) {
    // Process inputs and update parent
}

实际问题: 然后我从 PlayerGraphics 调用 update(Player * parent) 方法我得到错误 can't convert from 'Object *' to 'Player * '

对我来说,问题来自于继承,虽然我找不到我做错了什么。

【问题讨论】:

  • 仔细查看错误消息并查看错误发生的确切位置(文件 + 行号)可能会有所帮助。是在void update() { graphics-&gt;update(this); };吗?
  • 是的,在 PlayerGraphics.cpp 生成期间,graphics->update(this); 处触发错误。
  • 一个可以剪切并粘贴到Compiler Explorer 或类似内容中的最小示例会很有帮助。
  • 试试这个:static_cast(this)->update(this)

标签: c++ templates inheritance components


【解决方案1】:

您不能将基类隐式转换为派生类。演员表应该是明确的。

例如:

struct PlayerGraphics {
    using Parent = Player;
    void update(Parent* parent);
};
template<typename ComponentGraphics>
struct Object {
    void update() {
        using Parent = typename ComponentGraphics::Parent;
        graphics->update(static_cast<Parent*>(this));
    };
};

或使用类型特征:

template<typename ComponentGraphics>
struct Traits;

template<>
struct Traits<PlayerGraphics> {
    using Parent = Player;
};
template<typename ComponentGraphics>
struct Object {
    void update() {
        using Parent = typename Traits<ComponentGraphics>::Parent;
        graphics->update(static_cast<Parent*>(this));
    };
};

注意ComponentGraphicsObject内部的一个不完整类型,它的使用是有限的。例如,您可以在update() 正文中使用typename ComponentGraphics::Parent,但不能在其签名中使用。后一种情况需要类型特征类。

【讨论】:

  • 非常感谢:)。是更推荐使用特征还是两种解决方案相等?
  • @Poulpynator,在您的特定示例中,不需要 Traits 类,但这种方法更通用。例如,对于成员函数Object::func(),您不能说typename ComponentGraphics::Parent func(),但可以说typename Traits&lt;ComponentGraphics&gt;::Parent func()
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-18
  • 1970-01-01
  • 2018-05-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多