【问题标题】:How to use multi-inheritence with std::shared_ptr?如何使用 std::shared_ptr 的多重继承?
【发布时间】:2021-02-16 10:24:40
【问题描述】:

所以,我有这样的代码:

class IUpdatable {
    virtual void onUpdate() = 0;
};
class IDrawable {
    virtual void onDraw() = 0;
};
class IEventable {
    virtual void onEvent() = 0;
};

class IObject {};
class Button : public IObject, public IUpdatable, public IDrawable, public IEventable {/*override of virtual metothods*/};
class NonVisibleButton : public IObject, public IUpdatable, public IEventable {/*override of virtual methods*/}

int main(){
    std::vector <std::shared_ptr <IObject>> buttons = {
        new Button(),
        new NonVisibleButton()
    };
    std::vector <std::weak_ptr <IEventable>> eventables = {
        buttons.at(0),
        buttons.at(1)
    };
    std::vector <std::weak_ptr <IDrawble>> drawbles = {
        buttons.at(0)
    };
}

那么,我可以实现这一点以及如何实现吗?我想用不同容器中的按钮定期更新矢量。 (更准确地说,我有单独的线程来更新 IEventable 的子类的对象,绝对所有从 IEventable 继承的东西都在这里)

【问题讨论】:

标签: c++ stl shared-ptr


【解决方案1】:

这样的事情可能会起作用:

#include <vector>
#include <memory>

class IUpdatable {
public:
    virtual void onUpdate() = 0;
};
class IDrawable {
public:
    virtual void onDraw() = 0;
};
class IEventable {
public:
    virtual void onEvent() = 0;
};

class IObject {
public:
    virtual ~IObject() = default;
};

class Button : public IObject, public IUpdatable, public IDrawable, public IEventable {
public:
    void onUpdate() override {}
    void onDraw() override {}
    void onEvent() override {}
};

class NonVisibleButton : public IObject, public IUpdatable, public IEventable {
public:
    void onUpdate() override {}
    void onEvent() override {}
};

int main(){
    std::vector <std::shared_ptr <IObject>> buttons = {
        std::static_pointer_cast<IObject>(std::make_shared<Button>()),
        std::static_pointer_cast<IObject>(std::make_shared<NonVisibleButton>())
    };
    std::vector <std::weak_ptr <IEventable>> eventables = {
        std::dynamic_pointer_cast<IEventable>(buttons.at(0)),
        std::dynamic_pointer_cast<IEventable>(buttons.at(1))
    };
    std::vector <std::weak_ptr <IDrawable>> drawbles = {
        std::dynamic_pointer_cast<IDrawable>(buttons.at(0))
    };
}

老实说,我不会尝试将 Java 代码结构(接口、继承等)硬塞到 C++ 中...如果可能,请尝试 composition over inheritance

【讨论】:

  • 很好的答案。作为可能移至答案的附加提示: IObject 需要至少有一个虚函数才能算作多态对象,因此能够转换为它。由于 IObject 表示基类,因此选择了虚拟析构函数来保证正确销毁子类对象。当我们在继承中“移动”时,使用转换运算符 dynamic_cast。在这种情况下,从基地到基地。
【解决方案2】:

使用局部变量来保存ButtonNonVisibleButton。这样做的额外好处是不需要buttons.at 来引用它们。

int main(){
    auto b = std::make_shared<Button>();
    auto nvb = std::make_shared<NonVisibleButton>();
    std::vector <std::shared_ptr <IObject>> buttons = {
        b,
        nvb
    };
    std::vector <std::weak_ptr <IEventable>> eventables = {
        b,
        nvb
    };
    std::vector <std::weak_ptr <IDrawble>> drawbles = {
        b
    };
}

【讨论】:

    猜你喜欢
    • 2014-08-27
    • 2012-05-13
    • 2021-08-10
    • 1970-01-01
    • 2021-02-10
    • 1970-01-01
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多