C ++ RAII,原型设计模式和延迟初始化协同工作

时间:2013-06-03 07:00:43

标签: c++11 raii lazy-initialization

我正在努力坚持一些严格的设计模式,同时开发我现有的代码库,因为我希望我将在相当长的一段时间内继续努力,我希望它能像我一样灵活和干净。可能。然而,在尝试将所有这些设计模式结合起来解决我面临的当前问题时,我遇到了一些问题,我希望有人可以给我一些建议。

我正在研究一些基本的homebrewn GUI小部件,它们提供一些通用的点击/拖动/复制行为。表面上,用户单击窗口小部件,然后将其拖动到某处。拖动它之后,小部件将“出现”以克隆自身并让用户拖动这个新副本。

原型设计模式显然是为了使这种复制功能适用于许多类型的小部件。对于大多数物体,故事就在那里结束。 Prototype对象实际上是用户最终拖动的重复版本的相同副本。

但是,我要复制的其中一个对象附加了一些相当大的资源,因此在用户实际决定单击并拖动并随后复制该特定对象之前,我不想加载它们。输入延迟初始化。但这给我带来了一些难题。我不能让原型对象克隆自己,因为它需要在用户复制虚拟原型版本之前加载大资源。我也不热衷于在对象中加入一些逻辑,在克隆/复制后,检查发生了什么,并决定是否应加载这些资源。相反,一个有用的人建议我创建一种shell对象,当它被克隆时,它将返回这个包含资源的更多派生版本,允许我使用RAII和延迟初始化。

但是我在实现这个方面遇到了一些麻烦,我开始怀疑我是否能按照我认为应该这样做的方式来做。现在它看起来像这样:

class widgetSpawner : public widget {
public:
    widgetSpawner();
    ~widgetSpawner();

private:
    widget* mPrototypeWidget;       // Blueprint with which to spawn new elements
};

class widgetAudioShell : public widget {
public:

    widgetAudioShell(std::string pathToAudioFile);
    widgetAudioShell( const widgetAudioShell& other );
    ~widgetAudioShell();

    virtual widgetAudio* clone() const { return new widgetAudio(*this); };  

private:
    std::string mPathToAudioFile;
};


class widgetAudio : public widgetAudioShell {
public:

    widgetAudio(AudioEngineAudioTrack &aTrack);
    widgetAudio( const widgetAudio& other );
    widgetAudio( const widgetAudioShell& other );

    ~widgetAudio();

    virtual widgetAudio* clone() const { return new widgetAudio(*this); };  

private:

    AudioEngineAudioTrack &mATrack;
};

显然,这是不可行的,因为shell不知道使用它来派生新类的对象。所以它不能通过克隆功能返回它。但是,如果我保持两个继承方式独立(因为它们都从widget继承),那么编译器会抱怨缺乏协方差,我认为这是有意义的吗?或者也许是因为我再次遇到了在另一个之前正确定义一个的麻烦。

实际上,widgetAudioShell需要了解widgetAudio,因此它可以返回一个“新”副本。 widgetAudio需要知道widgetAudioShell,因此它可以在创建/克隆时读取它的成员函数。

如果我没有弄错的话,这个循环依赖是因为我喜欢使用引用而不是指针,如果我必须使用指针,那么突然我所有其他小部件都需要做同样的事情我会发现地狱般的。我希望有人能够用类似的东西提供一些智慧吗?

0 个答案:

没有答案