2011-02-01 62 views
1

去年我看到一些源代碼(C++),其作者在基類中聲明靜態函數,但將其定義留給派生類。我記得有一個約束,即只有一個派生類被允許定義上述靜態函數。委託給派生類的靜態方法定義(C++)

我知道重寫靜態方法是不可能的,但這個技巧正是我所需要的。我只是不能讓它在我的代碼中工作:)有沒有人知道這個功能?

讓我們看看爲什麼這會有用。假設我們有一些基類(Shape)及其派生類(Circle,Triangle ...)。假設Shape是我的核心架構的一部分,派生類被視爲插件。我不想在未來改變我的核心架構。所以我們有:

class Shape 
{ 
    //other stuff here 
    static Shape* Factory(); 
} 

class Circle:Shape 
{ 
    //other stuff here 
    static Shape* Factory(); 
} 

形狀是一種抽象類,它不會實現Factory方法。方法由一個(且僅有一個)派生類實現。在實現中派生類將返回自己的新實例,所以它只是一個工廠方法。這一招使得它的作者使用的客戶端類此靜態方法在下列方式:

class Client 
{ 
    public Shape* shape; 
    public Client(); 
    //other stuff here 
} 

在實現構造的,他有這樣的事情:

Client::Client() 
:shape(Shape::Factory()) 
{   
} 

這樣,他才能夠實例化「右」而不改變引擎中的核心類。當他想要在覈心類中使用其他形狀時,他只需要在該派生類中定義靜態的Factory方法(並刪除其他派生類中的現有方法)。

這樣我們就有了某種「靜態多態性」。我無法在網絡上找到有關此技術的任何信息。它甚至有名字嗎?如果在C#語言中可以實現這樣的功能,我特別感興趣? :)

在此先感謝,並抱歉我的英語不好。

回答

0

這聽起來像你試圖做的是在我看來有點混亂。感覺就像是一個Factory類和一個Singleton的組合,然後試圖將它們全部壓回到結果類層次結構中。

我能想到的最簡單的(不一定是最好的)解決方案是忘記了Circle::Factory()Shape::Factory()並且只有一個叫做get_default_shape()的免費函數。

class Shape 
{ 
}; 

class Circle: public Shape 
{ 
}; 

Shape * get_default_shape() 
{ 
    return new Circle; 
} 

Client::Client() 
:shape(get_default_shape()) 
{ 
} 

關於這個的好處的一點是,它的唯一get_default_shape需要包括Circle.h的實施,所有的定義需求是Shape類的前向聲明。

0

嗯。我還沒有看到你描述的是什麼。可能是因爲你引用的那段代碼在包含派生類的cpp文件中定義了基類的靜態函數。

// definition of Circle class 
..... 

Shape* Shape::Factory() 
{ 
    return new Circle(); 
} 

這不是在這個例子中有用的,但如果你想隱藏類的實現,只發佈一個抽象基類(以減少編譯時依賴)可能是一個有用的技巧。如果基類和派生類不在相同的dll/exe中,它將不起作用。

類似的東西可以在C#中通過使用IOC框架,使用泛型或在基類中註冊工廠delegate來實現。我傾向於更喜歡泛型和代表。

+0

刪除此評論 – Kovasandra 2011-02-02 09:38:30

+0

是的,靜態方法是在派生類的cpp文件中定義的。這正是我想要實現的:)但是我無法讓它在我的代碼中工作,因爲當我將靜態類定義放入派生類cpp文件時,編譯器報告基類不可訪問。我想我的問題的答案是:「檢查兩個類是否在相同的DLL/EXE」? :)你能告訴我更多關於C#委託和相同技巧的泛型版本嗎?提前致謝。 – Kovasandra 2011-02-02 09:45:24

相關問題