0

Say I have a base class and some derived classes:

class Base1
{
public:
    virtual ~Base1() {}
    virtual void update() = 0;
};

class Derive1 : public Base1
{
public:
    void update() override {/*...*/}
};

class Derive2 : public Base1
{
public:
    void update() override {/*...*/}
};

and somewhere to manage my derived objects:

class Base1Manager
{
public:
    void add(Base1* p)
    {
        objs.push_back(p);
    }
    void update()
    {
        std::for_each(objs.begin(), objs.end(), [](Base1* p) { p->update(); });
    }
    void clear()
    {
        std::for_each(objs.begin(), objs.end(), [](Base1* p) { delete p; });
        objs.clear();
    }
    std::vector<Base1*> objs;
};

Base1Manager bm1;
bm1.add(new Derive1());
bm1.add(new Derive2());

I can do update:

bm1.update();

finally I have to release the resources upon program exit:

bm1.clear();

The above scenario is fine, but the next is not:


The problem is when I add another base class and expand my derived classes:

NOTE: According to this answer: [Why should I avoid multiple inheritance in C++?, Point 3 and 4, my Base1 and Base2 are different concepts so the multiple inheritance should be fine here.

class Base1
{
public:
    virtual ~Base1() {}
    virtual void update() = 0;
};

class Base2
{
public:
    virtual ~Base2() {}
    virtual void do_different_thing() = 0;
};

class Derive1 : public Base1, public Base2
{
public:
    void update() override {/*...*/}
    void do_different_thing() override {/*...*/}
};

class Derive2 : public Base1, public Base2
{
public:
    void update() override {/*...*/}
    void do_different_thing() override {/*...*/}
};

Also imagine there is a new Base2Manager, basically the same as Base1Manager.

Finally my question is, how to properly release the resources?

Apparently I can not do the release twice:

bm1.clear();
bm2.clear();

I have to choose only 1 manager and let it do the job, but these 2 managers are made separately and does not know each other, so what's the proper way to handle it?

Would smart pointer help? Should I add an API like addButNotRelase(Base2* p) so that I can manipulate p but not own p (like put p in a vector other than objs?

4

1 回答 1

1

std::shared_ptr在这里有帮助,因为两位经理都拥有(可能相同的)指针。

在您的第一个示例中,只有一个经理,您可能已替换std::shared_ptrstd::unique_ptr.

如果其他类必须拥有该对象来控制生命周期,那么您可以在管理器中使用简单的指针。

用法应如下所示:

// The container
std::vector<std::shared_ptr<Base1>> base1s;
std::vector<std::shared_ptr<Base2>> base2s;

// The objects
std::shared_ptr<Derive1> d1 = std::make_shared<Derive1>();
std::shared_ptr<Derive2> d2 = std::make_shared<Derive2>();

// Feed the containers
base1s.push_back(d1);
base1s.push_back(d2);

base2s.push_back(d1);
base2s.push_back(d2);
于 2014-08-07T07:51:24.783 回答