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

时间:2010-06-20 15:42:58

标签: c++ inheritance polymorphism clone new-operator

所以这是交易:

我有一个具体的类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
    }
};

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

class Window
{
public:

private:
    IWindowType* mType;
};

我的问题是能够在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自己的副本来管理?我不需要保留这个设计,我只是在尝试做事的方式,所以如果有更好的设计方法,欢迎。

1 个答案:

答案 0 :(得分:0)

您是否需要访问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;
};

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