2013-03-07 80 views
3

我有3個班BCD,從一個基類A得出:廠功能 - 如何做到這一點的更好的方式

class A 
{ 
// body 
}; 

class B : public A 
{ 
// body 
}; 

class C : public A 
{ 
// body 
}; 

class D : public A 
{ 
// body 
}; 

我想創建一個工廠功能,可以讓我創建特定類型(BCD)的對象,併爲返回一個指向它A類:

typedef std::shared_ptr<A> a_ptr; 

a_ptr createObject(int type) 
{ 
    switch(type) 
    { 
    case 0: 
     return a_ptr(new B()); 
    break; 
    case 1: 
     return a_ptr(new C()); 
    break; 
    case 2: 
     return a_ptr(new D()); 
    break; 
    } 
} 

然後,如果我有例如B類型的指針,我想將工廠創建的對象指定給B。對我而言,唯一合理的解決方案是:

std::shared_ptr<B> b = std::shared_ptr<B>(dynamic_cast<B*>(createObject(0))); 

但它看起來很醜。有沒有更好的解決方案?或者,也許我應該嘗試用我的函數創建對象的不同方式?

+2

如果您基於運行時值創建對象(這裏是'int type'),那麼就沒有可能返回值被「正確」鍵入(如果'createObject'是一個模板,這將是可能的,但然後你只能夠靜態創建),所以需要強制轉換。你可以設計*隱藏它的方式,但恕我直言,這不是一個好主意。演員應該是突出的。 – Jon 2013-03-07 13:14:50

+1

C++是靜態類型的。也就是說,你必須在編譯時知道每個表達式的類型。 (在你的情況下,應該是'A'類型。) – 2013-03-07 13:15:59

+2

請注意,'shared_ptr's有自己的[cast methods](http://en.cppreference.com/w/cpp/memory/shared_ptr/pointer_cast)。 – 2013-03-07 13:18:04

回答

5

如果要執行運行時垂頭喪氣的一個shared_ptr的,而使用std::dynamic_pointer_cast<>

std::shared_ptr<B> b = std::dynamic_pointer_cast<B>(createObject(0)); 

如果該對象被創建的類型是在運行時決定的,而你是一個嘗試以檢查返回的對象是否具有類型B,那麼我看不到比動態向下轉換更好的替代方法。

在另一方面,如果你知道 100%的把握尖銳的物體的類型爲B,那麼你可以使用std::static_pointer_cast<>

std::shared_ptr<B> b = std::static_pointer_cast<B>(createObject(0)); 

在您100%的把握知道這一刻,但是,我不明白爲什麼這樣的指令不應該成爲:

std::shared_ptr<B> b = std::make_shared<B>(); 
+1

另外,我認爲重要的是要注意,在大多數情況下,動態投射的需要是代碼異味。你有你的共同基礎類,所以你可以避免投射。虛函數應該讓你得到每個類的不同行爲。如果你需要轉換來訪問派生類中的某些東西,那麼你的調用代碼將是一個很大的if-else或switch case,這表明你的類可能不應該從一個公共基礎派生出來。 – 2013-03-07 13:30:10

1

對於少數「類型」你的createObject看起來不錯。如果有很多「類型」,它只會變得很難看。然後,您可以通過爲相應類的工廠函數創建表格映射類型來獲得更好的效果。例如:

std::map<int, std::function <a_ptr()> > dispatcherTable = 
{ 
    {0, createB }, 
    {1, createC }, 
    {2, createD } 
}; 

然後,你可以用你的「類型」的一個索引表:

new_a = dispatcherTable[a](); 

那些「createB」,「createC」等可能的靜態成員的工廠類或B,C等類的靜態成員。你想要的任何方式。

+0

這可行,但開關櫃更具可讀性。我認爲這不是OP詢問的問題。 – 2013-03-07 13:25:37

相關問題