所以这是交易:
我有一个具体的类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自己的副本来管理?我不需要保留这个设计,我只是在尝试做事的方式,所以如果有更好的设计方法,欢迎。
答案 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;
};
这样,您不必担心如何从外部世界获取类型对象。他们只需要指定窗口应该是什么类型,窗口就决定了该类型的表示方式。