C++:混合和多态性

3
我正在尝试将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;
};

接下来我定义两个mixin ResizableMovable,代码如下:

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<Window>Movable<Resizable<Window>> 之间存在差异,因为后者的 Movable 可以使用 Resizable。 在我的设计中,这些混合组件是独立的,它们混合的顺序并不重要。 我猜这种使用混合组件的方式非常普遍。

在保持设计尽可能不变的情况下,有没有办法使这段代码编译通过?

1个回答

5

有没有办法在尽可能保持设计的情况下使此代码编译?

您可以通过模板化方法,使窗口管理器接受任意版本的Resizable<>Movable<>

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, ...
    }
};

非常感谢。正是我所期望的。 - Adam Dohnal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接