2016-11-23 112 views
2

假設我需要兩個工廠的抽象基類及其派生類(我沒有訪問實際的構造函數)。在效率和代碼風格方面,哪個是最好的構造?抽象基類和派生類的工廠函數的C++返回類型

1)讓所有工廠返回一個shared_ptr。這是統一的,但會導致許多派生類的不必要的shared_ptrs,因爲它們在客戶端代碼中直接取消引用。

std::shared_ptr<Derived> createDerived(Argument arg) 
{ 
    return std::make_shared<Derived>(arg); 
} 

std::shared_ptr<AbstractBaseClass> createABC(Argument arg) 
{ 
    if (suchAndSo(arg)) 
     return createDerived(arg); 
    else 
     return nullptr; // or createSomeOtherDerivedClass 
} 

int main() 
{ 
    Argument Arg; 
    Derived d = *createDerived(arg); 
    auto pAbc = createABC(arg); 
} 

2)設派生類的工廠返回一個值,並讓ABC工廠返回它是通過使用make_shared和源性拷貝構造(其導致許多拷貝構造調用構造的共享PTR)

Derived createDerived(Argument arg) 
{ 
    return Derived(arg); 
} 

std::shared_ptr<AbstractBaseClass> createABC(Argument arg) 
{ 
    if (suchAndSo(arg)) 
     return make_shared<AbstractBaseClass>(createDerived(arg)); 
    else 
     return nullptr; // or createSomeOtherDerivedClass 
} 

int main() 
{ 
    Argument Arg; 
    Derived d = createDerived(arg); 
    auto pAbc = createABC(arg); 
} 
+0

你打算做一些多態函數嗎? – doctorlove

+0

@doctorlove你不能有一個沒有多態的*抽象*基類(我認爲你的意思是*虛擬*)函數,你能嗎? :) – user2079303

回答

3

在ABC情況下,您可以簡單地返回一個unique_ptr,以避免開銷shared_ptr。但是,只有~AbstractBaseClass是虛擬的,這是一個選項。

通過返回unique_ptr,您允許調用方決定是否需要共享對象。


當返回一個具體類型的對象時,返回一個值確實是一個很好的選擇。這避免了動態分配的成本。

這導致許多拷貝構造函數調用

值返回工廠本身只複製如果對象是不動,constructible,如果優化沒有實現複製省略(其中任何像樣的優化器)。

您可以實現抽象指針返回工廠而不委託給返回工廠的值,而是直接構造對象以避免該複製(移動)。

0

這兩個工廠函數都應該返回簡單的指針。共享指針應該應用於他們的結果。

使用工廠方法以邏輯術語選擇合適的構造函數與管理對象所有權(通過共享指針)不同。