Carmelo Evoli
Carmelo Evoli

Reputation: 23

Creating a std::vector of derived classes

Assume that I have an Abstract Class

class AbstractClass {
public:
    virtual int get() const = 0;
};

and two different Derived classes

class DerivedClassA : public AbstractClass {
public:
    int get() const override { return 1; }
};

class DerivedClassB : public AbstractClass {
public:    
    int get() const override { return 2; }
};

and I want to pass a std::vector of Abstract Classed to a given function:

int f(const std::vector<std::shared_ptr<AbstractClass> >& classes) { ... }

What I'm doing is this:

int main () {
    std::vector<std::shared_ptr<AbstractClass> > _classes;
    std::shared_ptr<AbstractClass> _derivedA = std::make_shared<DerivedClassA>();
    _classes.push_back(_derivedA);
    std::shared_ptr<AbstractClass> _derivedB = std::make_shared<DerivedClassB>();
    _classes.push_back(_derivedB);
    std::cout << f(_classes) << "\n";
}

It does work but I'm wondering if there is a more compact form to write it in modern C++? I've tried using auto in some places but it always gives an error, or to build the derived classes in place, but it doesn't work as well.

Upvotes: 0

Views: 324

Answers (2)

Expurple
Expurple

Reputation: 921

Besides what @eeronika is suggesting, you can also implicitly call std::shared_ptr constructor by passing raw pointers:

int main () {
    std::vector<std::shared_ptr<AbstractClass> > _classes;
    _classes.emplace_back(new DerivedClassA);
    _classes.emplace_back(new DerivedClassB);
    std::cout << f(_classes) << "\n";
}

Upvotes: -1

eerorika
eerorika

Reputation: 238311

It does work but I'm wondering if there is a more compact form to write it

You could get rid of the intermediate variables to make it more compact:

f({
    std::make_shared<DerivedClassA>(), 
    std::make_shared<DerivedClassB>(),
});

Since all access specifiers are public, you can make the class definitions more compact by using struct:

struct DerivedClassB : AbstractClass {
    int get() const override { return 1; }
};

Upvotes: 6

Related Questions