简体   繁体   中英

C++ Storing child objects in a common container

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

namespace Core {
    class Sparse;
    class Dense;
}

I define those classes somewhere and after that I derive 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 common container that can be accessible from anywhere. How can I do this?

And another question: Should I include the child classes in the Core namespace aswell?

Thank you.

As long classes Sparse and Dense are unrelated, you can't store instances of derived classes in the same c++ standard container (unless you're going to use such fancy stuff as boost::variant or boost::any ).

If you give them a common (abstract) base class you can use smart pointers ( eg std::unique_ptr<> or std::shared_ptr ) to keep referencing them in a container (using the same pseudo syntax as in your sample)

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

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

Another option might be a template wrapper class solution

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 to loosely couple classes like Sparse and Dense within a single container, but still at least requires some abstract interface, that could be be used behaviorally consistent for both classes, and classes derived from them.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM