Storing objects with multiple inheritance in a container

The library that I use has many types, all of which come from the same two interfaces:

class Huey : public IDuck, public ICartoonCharacter
{
...
};

class Dewey : public IDuck, public ICartoonCharacter
{
...
};

class Louie : public IDuck, public ICartoonCharacter
{
...
};

I would like to store objects of all the above types in a wrapper class and insert objects of this wrapper class into a container. Of course, I would have to call methods belonging to both interfaces from my wrapper class.

What are my options here? I could think of

  • save IDuck *in my wrapper and dynamic_cast-ing before ICartoonCharacteror
  • using something like boost::any, making my shell a class template, with a pair static_asserts, to ensure that the template parameter inherits from IDuckand ICartoonCharacter.

but none of the options, especially appeals. Any ideas?

, ? - , , 3 .

EDIT: , . public .

EDIT: dynamic_cast dynamic_cast ( ).

: , . , . !

+4
3

:

struct CartoonDuckWrapper {
    IDuck * duck;
    ICartoonCharacter * toon;

    template <class CartoonDuck>
    CartoonDuckWrapper(CartoonDuck & cd) : duck(&cd), toon(&cd) {}
};

static_assert , CartoonDuck , , .

(, , ), , dynamic_cast . static_cast "-" .

+5

, , .

class ICartoonDuck: public IDuck, public ICartoonCharacter {};

template <typename T>
class CartoonDuck: public ICartoonDuck {
public:
    explicit CartoonDuck(T t): _t(std::move(t)) {}

    // IDuck interface
    virtual void foo() override { t.foo(); }

    // ICartoonCharacter interface
    virtual void bar() override { t.bar(); }

private:
    T _t; // or any ownership scheme that makes sense
}; // class CartoonDuck

template <typename T>
CartoonDuck<T> makeCartoonDuck(T t) { return CartoonDuck(std::move(t)); }

template <typename T, typename... Args>
std::unique_ptr<CartoonDuck<T>> makeUniqueCartoonDuck(Args&&...) {
    return std::unique_ptr<CartoonDuck<T>>(new T(std::forward<Args>()...);
}

std::unique_ptr<ICartoonDuck> .

:

std::vector<std::unique_ptr<ICartoonDuck>> cartoonDucks;
cartoonDucks.push_back(makeUniqueCartoonDuck<Huey>());
cartoonDucks.push_back(makeUniqueCartoonDuck<Dewey>());
cartoonDucks.push_back(makeUniqueCartoonDuck<Louie>());

for (std::unique_ptr<ICartoonDuck> const& cd: cartoonDucks) {
    cd->foo();
    cd->bar();
}
+3

:

class ILuckyDuck: public IDuck, ICartoonCharacter //...

:

class Huey : public ILuckyDuck //...

.. :

std::vector<std:shared_ptr<ILuckyDuck>> donald;
+2
source

All Articles