C ++ Storing child objects in a shared container

I have a set of abstract parent classes in a namespace similar to the following

namespace Core {
    class Sparse;
    class Dense;
}

      

I define these classes somewhere and after that I get some child classes:

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

      

Now I want to instantiate some objects of the child classes and store them in a shared container accessible from anywhere. How can i do this?

And one more question: should child classes be included in the namespace Core

?

Thank.

+3


source to share


1 answer


Since the classes are long Sparse

and are Dense

not related to each other, you cannot store instances of derived classes in the same standard C ++ container (unless you intend to use fancy stuff like boost::variant

or boost::any

).

If you give them a generic (abstract) base class, you can use smart pointers (like std::unique_ptr<>

or std::shared_ptr

) to reference them in the container (using the same pseudo syntax as in your example)

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

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

      




Another option could be to solve a wrapper-template class

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>>());

      

The latter will allow you to freely mix classes such as Sparse

and Dense

in the same container, but still requires at least an abstract interface that can be used in a behaviorally consistent manner for both classes and classes derived from them.

+2


source







All Articles