将派生对象作为基指针存储在另一个对象中 (C++)

发布于 2024-09-06 04:39:47 字数 1525 浏览 4 评论 0原文

所以事情是这样的:

我有一个具体的 Window 类,代表一个将用于绘图的操作系统窗口。窗口可以采用多种类型,例如全屏、固定窗口、可调整大小的窗口、无边框窗口等。这是使用接口 IWindowType 实现的,其中特定类型派生自(类被剥离以集中于点)。

class IWindowType
{
public:
    virtual void createWindow(unsigned short width, unsigned short height) = 0;
};

class FixedWindow: public IWindowType
{
public:
    virtual void createWindow(unsigned short width, unsigned short height) 
    { 
         // Fixed window creation implementation
    }
};

可以派生任何进一步的实现,或者可以轻松更改底层窗口创建方法。窗口需要存储它的类型,以便它可以在需要时重新调用 createWindow(),以实现显式窗口大小调整或完整类型更改(例如固定为全屏)。因此,它存储了一个IWindowType指针。

class Window
{
public:

private:
    IWindowType* mType;
};

我的问题是能够将类型存储在 Window 内,让 window 负责管理它的类型。对于这种设计,我有两种解决方案,但我并不喜欢其中的外观。

首先是让客户端传递动态分配的窗口类型并让窗口处理内存释放。

Window testWindow;
testWindow.setType(new FixedWindow());

这确实有效,但它需要记住传递动态分配的对象,以及丑陋地使用 new 而不匹配删除(无论如何,就客户端而言)。

我在研究后发现的第二个方法是使用虚拟clone()方法,该方法也可以工作并且具有更好的语法,因为它执行传入的任何派生类的深层复制,并且窗口控制这个复制的对象。

IWindowType* FixedWindow::clone() const
{
    return new FixedWindow(*this);
} 

void Window::setType(const IWindowType& type)
{
    if(mType)
        delete mType;

    mType = type.clone()
}

Window testWindow;
testWindow.setType(FixedWindow());

然而,我觉得为每个需要此功能的类创建一个clone()方法(我可以看到很多类需要这种设计)不仅会变得乏味,而且clone()可能会在这种情况下使用,我真的不想要。

所以我的问题是:是否有其他方法可以将传递给 setType() 的派生类型的所有权传递给 Window,即为 Window 提供自己的副本来管理?我不需要保留这个设计,我只是在尝试做事的方法,所以如果有更好的设计方法可用,欢迎。

So here's the deal:

I have a concrete class Window, representing an operating system window which will be be used for drawing. Window can take on many types, such as fullscreen, fixed window, resizable window, borderless window etc. This is implemented using an interface IWindowType, in which the specific types derive from (classes are stripped down to focus on the point).

class IWindowType
{
public:
    virtual void createWindow(unsigned short width, unsigned short height) = 0;
};

class FixedWindow: public IWindowType
{
public:
    virtual void createWindow(unsigned short width, unsigned short height) 
    { 
         // Fixed window creation implementation
    }
};

Any further implementations can be derived, or the underlying window creation method can be changed easily. Window needs to store it's type so it can re-call createWindow() if it needs to, for an explicit window resize or a complete type change (e.g. fixed to fullscreen). Therefore, it stores an IWindowType pointer.

class Window
{
public:

private:
    IWindowType* mType;
};

My problem is being able to store the type inside Window, giving window the responsibility for managing it's type. I have two solutions with this design, neither of which I really like the look of.

First is to have the client pass a dynamically allocated window type and have window deal with memeory de-allocation.

Window testWindow;
testWindow.setType(new FixedWindow());

This does work, but it requires remembering to pass a dynamically allocated object, as well as an ugly use of new with no matching delete (as far as the client is concerned, anyway).

The second I found after research was the use of a virtual clone() method, which also works and has much better syntax, since it performs a deep copy of whatever derived class is passed in, and window takes control of this copied object.

IWindowType* FixedWindow::clone() const
{
    return new FixedWindow(*this);
} 

void Window::setType(const IWindowType& type)
{
    if(mType)
        delete mType;

    mType = type.clone()
}

Window testWindow;
testWindow.setType(FixedWindow());

However, I feel creating a clone() method for each class that requires this functionality (I can see a lot of classes requiring it with this kind of design) can become not only tedious, but clone() may be used out of this context, which I don't really want.

So my question: Are there any other ways to pass ownership of the derived type passed to setType() to Window i.e. giving Window it's own copy to manage? I don't require to keep this design, I am simply experimenting ways of doing things, so if a better design approach is available, it is welcome.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

掩耳倾听 2024-09-13 04:39:47

您是否需要访问 Window 类之外的那些类型对象?如果您不这样做,我会尝试隐藏您正在使用类来表示类型的事实。也许你可以这样做:

class Window
{
public:
    enum WindowType
    {
        FixedWindow,
        //more types
    };

    void setType(WindowType type)
    {
        delete mtype;

        //move type creation to some factory class
        mtype = TypeFactory::createType(type);
    }

private:
    IWindowType* mType;
};

这样,你就不必担心如何从外界获取类型对象。他们只需要指定窗口应该是什么类型,窗口决定如何表示该类型。

Do you need access to those type objects outside the Window class? If you don't, I would try to hide the fact that you're using a class to represent the type. Maybe you could do something like this:

class Window
{
public:
    enum WindowType
    {
        FixedWindow,
        //more types
    };

    void setType(WindowType type)
    {
        delete mtype;

        //move type creation to some factory class
        mtype = TypeFactory::createType(type);
    }

private:
    IWindowType* mType;
};

This way, you don't have to worry about how to get the type objects from the outside world. They just have to specify what kind of type the window should be, the window decides how that type is represented.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文