Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using base class rather than base pointer to work on derived class

I have a base abstract class like this;

class X {
public:
    virtual ~X(){}
    virtual doSomething() = 0;
};

Then I am implementing this with couple of classes like Y, Z etc. each having their own constructor, destructor and doSomething implementation. In my main function I do;

int main(){
    std::vector<X *> v;
    X *x1 = new Y();
    X *x2 = new Z();
    v.push_back(x1);
    v.push_back(x2);
    for(auto p : v){
        p->doSomething()
    }
}

This calls respective doSomething implementations as expected. But my problem is that I am using pointers to abstract class to manipulate a hierarchy of derived classes through its base class. This forces me to use new to create instances on the heap and I have to delete them manually afterwards. Is there a way to do something like this;

int main(){
    std::vector<X> v;
    Y x1();
    Z x2();
    v.push_back(x1);
    v.push_back(x2);
    for(auto p : v){
        p.doSomething()
    }
}

So that destructors will be called automatically when I get out of main. I know I can't create a member of abstract class but using pointers to achieve all this seems strange. Surely there must be a way of doing this without pointers and new-delete. It would be great if someone showed me the best practice.

like image 331
meguli Avatar asked Mar 12 '23 10:03

meguli


1 Answers

You want to use an appropriate smart pointer:

std::vector<std::unique_ptr<X>> v;

v.push_back(std::make_unique<Y>());
v.push_back(std::make_unique<Z>());

// all done

(There are of course still dynamic allocations, since you cannot manage an unbounded number of unconstrained types without runtime indirection, but you should never have to think about any of the dynamic management manually. The type system can do all the work for you.)

like image 108
Kerrek SB Avatar answered Apr 30 '23 22:04

Kerrek SB