2

我有两个继承相同抽象基类的类:

class base
{ virtual void something() = 0; };

class a : public base
{
     void something();
};

class b : public base
{
     void something();

     // This is what I want: a list where I can store values of type a
     // and of type b
     // std::list<a & b> objs;
};

我可以使用原始/智能指针列表 ( list<base*> obj_ptrs),但如何使用此列表?

b b_obj;
b_obj.obj_ptrs.push_back(new a());

// Who have to delete this pointer? Who use the class or who design
// the class in the object destructor?

// The following is valid for c++11
auto p = b_obj.obj_ptrs.back();
// But if i'm using c++03?

我希望使用该课程的人有可能这样做:

a a_obj;
b b_obj;

b_obj.obj_ptrs.push_back(a);
b_obj.obj_ptrs.push_back(b);

我该如何设计我的课程来完成这项工作?

4

4 回答 4

4

我可以使用原始/智能指针列表 ( list<base*> obj_ptrs),但如何使用此列表?

您可以通过调用虚函数与​​它们进行多态交互,或者在特殊情况下,使用dynamic_cast将指针类型转换为a*or b*

谁必须删除这个指针?

您将不得不决定所有权计划。一种方法是将智能指针(通常unique_ptr,或者shared_ptr在特殊情况下)存储在列表中,然后在从列表中删除时自动删除它们。另一种方法是将对象与列表分开管理,并将原始指针放入列表中。

// The following is valid for c++11
auto p = b_obj.obj_ptrs.back();
// But if i'm using c++03?

这相当于base * p = b_obj.obj_ptrs.back();. auto不会神奇地给出动态指针类型,它只是静态指针类型的快捷方式。

我该如何设计我的课程来完成这项工作?(存储不同类型的对象)

存储不同类型的对象可以使用有区别的联合来完成- 基本上,一个带有一些额外元数据的联合来跟踪哪个联合成员处于活动状态。这些在 C++ 中实现起来非常棘手,但您可以使用Boost.VariantBoost.Any。这样做的好处是您不需要一个通用的基类,或者来自所存储类型的任何其他支持;可以使用任何一组(非抽象)类型。

于 2012-07-05T12:51:08.973 回答
2

使用共享指针列表非常安全且非常简单:

std::list<std::shared_ptr<base>> the_list;

如果您遵守规则,您添加的任何对象都将被分配,当对象不再被引用计数时,将为您处理删除newshared_ptrshared_ptr实现引用计数)

std::shared_ptr<a> my_a(new a);
std::shared_ptr<b> my_b(new b);

the_list.push_back(my_a);
the_list.push_back(my_b);

std::shared_ptr<base> my_object = the_list.back();
于 2012-07-05T12:49:46.510 回答
0

std::list<a & b>对象;不正确。我想你的意思是std::list<base*> objs或者std::list<base&> objs 所以,对于添加元素做

a a_obj;
b b_obj;
b_obj.objs.push_back(&a_obj);
b_obj.objs.push_back(&b_obj);
base* p = b_obj.objs.back();

或使用引用而不是指针。

于 2012-07-05T12:46:04.027 回答
0

如果你真的,真的只关心存储类型的值,a或者b和那些类型的值,那么考虑在内部拥有一个std::list<a>和一个std::list<b>,并在两者上重载一个适当的公共成员a并将b其转发到适当的列表(例如,这b obj; obj.push_back(value);将是首选用法)。

只要您不关心ab对象之间插入的相对顺序,不需要您担心所有权,与使用 eg 相比,不支付动态分配的成本std::unique_ptr<base>并表达最接近的内容,这项工作就可以了.

于 2012-07-06T06:50:12.410 回答