2014-11-04 34 views
3

我有一個命名空間中的一組抽象父類的對象,類似於以下C++中存儲的孩子在一個共同的容器

namespace Core { 
    class Sparse; 
    class Dense; 
} 

我某處定義這些類之後,我得到一些子類:

class SparseA: public Core::Sparse; 
class SparseB: public Core::Sparse; 
class DenseA: public Core::Dense; 

現在我想實例化子類的一些對象,並將它們存儲在可從任何地方訪問的公共容器中。我怎樣才能做到這一點?

還有一個問題:我是否應該在Core命名空間中包含子類?

謝謝。

+1

你想在容器中混合稀疏和密集?如果是這樣,你確定這是你正在尋找的設計? – 2014-11-04 18:19:22

+0

'boost :: variant ,std :: unique_ptr >' – 2014-11-04 18:20:22

+0

@KarolyHorvath這可能是另一個問題。我可能需要也可能不需要這些對象,所以我將隨時創建它們(類似於每個對象的Factory),並且我需要在Console對象中訪問它們,所以我想將它們全部存儲在同一個地方。你有沒有其他的設計建議? – manatttta 2014-11-04 18:24:15

回答

2

只要類SparseDense無關,你不能存儲在同一個C++標準集裝箱派生類的實例(除非你打算使用這種花哨的東西,boost::variantboost::any)。

如果你給他們一個共同的(抽象)基類,你可以使用智能指針(如std::unique_ptr<>std::shared_ptr),以保持在一個容器中引用它們(使用相同的僞語法您樣本中)

namespace Core { 
    class CommonBase; 
    class Sparse : public CommonBase; 
    class Dense : public CommonBase; 
} 

typedef std::vector<std::unique_ptr<Core::CommonBase>> MyContainerType; 

另一種選擇可能是一個模板包裝類解決方案

namespace Core { 
    class WrapperBase { 
    public: 
     // Expose the common interface of Sparse and Dense as 
     // pure virtual functions 
     virtual void foo() = 0; 
     virtual ~WrapperBase() {}    
    }; 

    template<class Impl> 
    class Wrapper : public WrapperBase { 
    private: 
     Impl& impl_; 

    public: 
     Wrapper(Impl& impl) : impl_(impl) {} 
     void foo() { 
      impl.foo(); // Delegate to the actual implementation 
     } 
    }; 

    class Sparse; 
    class Dense; 
} 

typedef std::vector<std::unique_ptr<Core::WrapperBase>> MyContainerType; 

MyContainerType container; 

container.push_back(std::make_unique<Wrapper<SparseA>>()); 
container.push_back(std::make_unique<Wrapper<SparseB>>()); 
container.push_back(std::make_unique<Wrapper<DenseA>>()); 

後者將允許鬆散地耦合類,比如SparseDense,但仍然至少需要一些抽象接口,可以使用行爲上一致的兩個類和從它們派生的類。

+0

這是一個很好的設計?或者你有更好的建議? – manatttta 2014-11-04 18:26:24

+1

@manatttta _「這是一個很好的設計嗎?」_嗯,具體取決於你想要解決的問題。至少它工作和健壯。 – 2014-11-04 18:28:14

相關問題