Home > database >  C vector of classes which implement multiple virtual classes?
C vector of classes which implement multiple virtual classes?

Time:01-28

I'm looking to have an vector of class instances which implement multiple virtual classes.

e.g.

// assume that all the classes here have implementations

class A
{
public:
    virtual void doThing();
};

class ImplementsA
    : public A
{
public:
    void doThing() override;
};

class B
{
public:
    virtual void doSomethingElse();
};

class ImplementsB
    : public B
{
public:
    void doSomethingElse() override;
};

class AB
    : public A
    , public B
{
public:
    void doThing() override;
    void doSomethingElse() override;
};

class OtherAB
    : public A
    , public B
{
public:
    void doThing() override;
    void doSomethingElse() override;
    // these implementations are different than in AB
};

int main()
{
    // here I'd like to have a vector of classes AB and OtherAB, and any other classes which implement both A and B
}

I've been poking around but I haven't found any information about how to do this. Is this possible in C ? If so, how would the vector be structured/initialized to allow it?

Thank you!

CodePudding user response:

You need the Adapter and/or the Proxy and/or the Decorator design pattern. Try to wrap all the inheritance in ABwrapper : public A, public B and create a vector of ABwrapper

class ABWrapper: public A, public B
{
public:
    A *a; B *b; AB *ab;
    void doThing() 
    {
        if (this->ab==nullptr) {this->a->doThing(); return;}
        this->ab->doThing();
    }
    void doOtherThing() 
    {
        if (this->ab==nullptr) {this->b->doOtherThing(); return;}
        this->ab->doOtherThing();
    }
}

...
Vector<ABWrapper>

CodePudding user response:

There are various ways to go about it:

  1. Create a bundling interface, and manage your objects using pointers to them.
    This runs counter to the interface-segregation-principle, and pre-supposes that you can modify all the affected classes.

Still, if you can do it and accept the drawback, it's the most efficient choice.

  1. Save a pointer to each interesting interface.

If you need at most two interfaces, this is the second most efficient choice. Space use obviously increases linearly.

  1. Write your own wrapper abstracting the differences away. See smart-pointer and std::function for ideas.

  2. Use std::any and a map for registering how to access the interface. If few statically known fully derived types are involved, static functions might serve, and std::variant is enough.

  •  Tags:  
  • Related