2010-08-28 26 views
3

我有一個系統類,可以返回指向編輯器類的指針。 編輯器類在系統類中實例化並且通過指向系統的私有變量。該類實質上充當了系統的內部數據結構的替代接口。C++模式禁止在特定範圍之外的類的實例化?

我的問題: 做了設計模式存在,讓我禁止編輯類的直接實例,但不知何故仍然初始化它系統裏面?

謝謝。

+0

您描述的設計模式是所謂的「PIMPL成語」的變體。 – greyfade 2010-08-28 15:09:09

回答

6

你可以讓Editor的構造函數保持私有狀態,這樣可以防止其他人實例化它,然後讓系統成爲朋友將允許它訪問構造函數。

class System { 
public: 
    System() : editor_(new Editor()) { ... } 

private: 
    Editor* editor_; 
} 

class Editor { 
    friend class System; 
    Editor() { ... } 
} 
+0

這樣做的好處是不會使編輯器的成員函數間接(虛擬),這對每次調用都是一個小的(約7ns)CPU節省。 – Crashworks 2010-08-28 01:31:59

+0

啊,這個朋友的東西正是我所需要的。對我來說新概念,謝謝。 – leo 2010-08-28 01:40:42

+0

在這種方法中,編輯器不再是System類的接口。它不再爲外界所知。! – Chubsdad 2010-08-28 02:46:36

1

您可以爲您的編輯器創建抽象接口,並將實現嵌套在System的定義中。它甚至可以是protectedprivate

class IEditor 
{ 
public: 
    virtual int Whatever() = 0; 
}; 

class System 
{ 
public: 
    int foo; 
    IEditor *GetEditor() { return &m_Editor; } 

protected: 
    class Editor 
    { 
    virtual int Whatever() { return 1; } 
    // etc... 
    } 

    Editor m_Editor; 
} 
+0

+1我是抽象接口的粉絲;儘管嵌套類可能會變得混亂。 – joshperry 2010-08-28 01:56:44

0

如果你不想讓嵌套類,你可以使類編輯系統的朋友,使編輯的構造和析構私人。這樣,只有系統被允許實例化和銷燬類編輯器的實例。

0

考慮將複製構造函數和複製賦值與構造函數一起私有化。下面的例子顯示,如果這兩個方法不是私有的,則可以創建editor1和editor2。

class Editor { 
private: 
    Editor(); 
    friend class System; 
}; 

class System { 
public: 
    Editor editor; 
}; 

int main() { 
    System system; 
    Editor editor1(system.editor); 
    Editor editor2 = system.editor; 
    return 0; 
} 
0

爲什麼不將System的狀態拆分成另一個類?例如:

class SystemState { 
}; 

class Editor { 
    public: 
     Editor(SystemState &state) : 
      state(state) { 
     } 

    private: 
     SystemState &state; 
}; 

class System { 
    public: 
     System() : 
      editor(new Editor(state)) { 
     } 

    private: 
     SystemState state; 

     Editor *editor; 
};