簡體   English   中英

將派生對象存儲在另一個對象中作為基本指針(C ++)

[英]Storing a derived object inside another object as a base pointer (C++)

所以這是交易:

我有一個具體的類Window,代表一個將用於繪圖的操作系統窗口。 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負責管理其類型。 我對此設計有兩種解決方案,但我都不喜歡它們的外觀。

首先是讓客戶端傳遞動態分配的窗口類型,並讓窗口處理內存的解除分配。

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它自己的副本來管理? 我不需要保留這種設計,我只是在嘗試做事的方式,因此,如果有更好的設計方法可用,那么它是受歡迎的。

您是否需要訪問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;
};

這樣,您不必擔心如何從外界獲取類型對象。 他們只需要指定窗口應該是哪種類型,窗口就可以確定該類型的表示方式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM