【问题标题】:C++: Mixins and polymorphismC++:混合和多态
【发布时间】:2018-12-06 21:20:22
【问题描述】:

我正在尝试使 Mixin 模式适合我的问题,但我遇到了一个多态性问题,我不知道如何有效地解决这个问题。在尝试重新设计我的程序之前,我想征求您的意见(也许有一些我不知道的很酷的 c++ 功能)。

我想以非常直接和简单的方式呈现它,所以这里的用例可能没有意义。

我只有一个 Window

struct WindowCreateInfo {
    std::string title;
    int x, y;
    int width, height;
};

class Window {
public:
    Window(const WindowCreateInfo &createInfo) :
            title(createInfo.title),
            x(createInfo.x),
            y(createInfo.y),
            width(createInfo.width),
            height(createInfo.height) {}

    const std::string &getTitle() const { return title; }

    int getX() const { return x; }

    int getY() const { return y; }

    int getWidth() const { return width; }

    int getHeight() const { return height; }

public:
protected:
    std::string title;
    int x, y;
    int width, height;
};

然后我定义两个mixinResizableMovable如下

template<class Base>
class Resizable : public Base {
public:
    Resizable(const WindowCreateInfo &createInfo) : Base(createInfo) {}

    void resize(int width, int height) {
        Base::width = width;
        Base::height = height;
    }
};

template<class Base>
class Movable : public Base {
public:
    Movable(const WindowCreateInfo &createInfo) : Base(createInfo) {}

    void move(int x, int y) {
        Base::x = x;
        Base::y = y;
    }
};

接下来,我有一些业务层,我在其中处理 Window 的实例

class WindowManager {
public:
    static void resize(Resizable<Window> &window, int width, int height) {
        window.resize(width, height);

        // any other logic like logging, ...
    }

    static void move(Movable<Window> &window, int x, int y) {
        window.move(x, y);

        // any other logic like logging, ...
    }
};

这里明显的问题是下面的编译不通过

using MyWindow = Movable<Resizable<Window>>;

int main() {
    MyWindow window({"Title", 0, 0, 640, 480});

    WindowManager::resize(window, 800, 600);

    // Non-cost lvalue reference to type Movable<Window> cannot bind
    // to a value of unrelated type Movable<Resizable<Window>>
    WindowManager::move(window, 100, 100);
};

我了解Movable&lt;Window&gt;Movable&lt;Resizable&lt;Window&gt;&gt; 之间存在差异,因为后者Movable 可以使用Resizable。在我的设计中,mixin 是独立的,它们混合的顺序无关紧要。我想这种 mixins 的使用很常见。

有什么方法可以在尽可能保持设计的同时编译这段代码?

【问题讨论】:

    标签: c++ mixins


    【解决方案1】:

    有没有什么方法可以让这段代码在尽可能保持设计不变的情况下编译?

    您可以简单地通过模板化方法使窗口管理器接受Resizable&lt;&gt;Movable&lt;&gt; 的任意版本:

    class WindowManager {
    public:
        template<typename Base>
        static void resize(Resizable<Base> &window, int width, int height) {
            window.resize(width, height);
    
            // any other logic like logging, ...
        }
    
        template<typename Base>
        static void move(Movable<Base> &window, int x, int y) {
            window.move(x, y);
    
            // any other logic like logging, ...
        }
    };
    

    【讨论】:

    • 非常感谢。正是我所希望的。
    猜你喜欢
    • 1970-01-01
    • 2021-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多