【发布时间】:2014-09-30 08:31:49
【问题描述】:
假设我有一个基类和一些派生类:
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 {/*...*/}
};
以及管理我的派生对象的地方:
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());
我可以更新:
bm1.update();
最后我必须在程序退出时释放资源:
bm1.clear();
上面的场景没问题,下一个就不行了:
问题是当我添加另一个基类并扩展我的派生类时:
注意:根据这个答案:
[Why should I avoid multiple inheritance in C++?,第 3 点和第 4 点,我的 Base1 和 Base2 是不同的概念,所以这里的多重继承应该没问题。
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 {/*...*/}
};
还想象有一个新的Base2Manager,与Base1Manager基本相同。
最后我的问题是,如何正确释放资源?
显然我不能两次发布:
bm1.clear();
bm2.clear();
我只需要选择1个经理,让它做这个工作,但这2个经理是分开做的,彼此不认识,那么正确的处理方法是什么?
智能指针有帮助吗?我是否应该添加像addButNotRelase(Base2* p) 这样的API,以便我可以操作p 但不拥有p(比如将p 放入vector 而不是objs?
【问题讨论】:
-
只调用 clear 一次真的会造成任何麻烦吗?
-
这看起来像是共享所有权,应该适合
std::shared_ptr。或者,如果shared_ptr不合适,您可以滚动自己的引用计数。 -
@user2040251 问题是这些经理彼此不认识,所以决定谁应该拥有资源有点棘手。
标签: c++ polymorphism multiple-inheritance resource-management