【问题标题】:About C++ types, and vectors关于 C++ 类型和向量
【发布时间】:2011-08-20 02:40:30
【问题描述】:

假设我有几节课

Alpha 类(基类)

类 Beta(子类 Alpha)

类 Delta(子类 Alpha)

是否可以创建一个vector<Alpha> 并将 Alpha、Beta 和 Delta 类型的对象实例都存储在该向量中,并让该向量正常运行?

如果不是,假设我想拥有某种类似的功能,最好的方法是什么?

【问题讨论】:

  • 如果您使用基类指针/智能指针,那么可以。如果您存储值对象(而不是指向对象的指针),那么最大的担忧是对象切片(如果您有 virtual 方法等可能会出现意外行为)。
  • 您是否希望元素根据它们是 Alphas、Betas 还是 Deltas 而表现出不同的行为?还是您希望他们在vector 中时都表现得像Alphas? (无法想象第二个的用途,但也许你想要它。)
  • 它们需要表现得像 Beta 和 Delta 一样,并且它们会有一些需要执行的通用方法名称。 Seth 的虚方法声明听起来非常接近我的需要。只要虚拟方法调用可以窥探到实际对象的属性,我就会被设置。
  • 那么你真的想在你的类中使用virtual 方法,然后使用指向基类的指针(最好是智能指针),并将它们存储在你的向量中。每个类的virtual 方法都可以访问其所属类的成员字段(但只能访问父类的publicprotected 成员)。
  • @Jasconius - 我也这么认为。 Seth 的版本是您所需要的,但如果您想避免内存管理,您可以使用 Ethan 建议的智能指针。是的,虚拟方法可以做任何常规方法可以做的事情。 唯一的区别在于,在Alpha *a = new Beta; a->method() 中,如果method 是常规的,它将调用Alpha::method,但如果它是虚拟的,它将调用Beta::method。 (这样做的成本要高得多,因此并非所有方法都应该是虚拟的,但它是 C++ - 您只需为需要的部分付费。)

标签: c++ oop vector subclassing


【解决方案1】:

一种方法是使用一个充满指针的向量,并在基类中将每个指针共有的函数设为virtual

class Alpha {
public:
    virtual void dosomething() { /* do something as an alpha */ }
};

class Beta : public Alpha {
public:
    void dosomething() { /* do something as a beta */ }
};

class Delta : public Alpha {
public:
    void dosomething() { /* do something as a delta */ }
};

vector<Alpha*> v;
v.push_back(new Alpha);
v.push_back(new Beta);
v.push_back(new Delta);

v[1]->dosomething(); // calls Beta's dosomething

但是,您必须小心使用这种方法,以确保 delete 您将 new 放入容器中的所有内容。你可以使用智能指针并避免这个警告:

vector<shared_ptr<Alpha> > v;
v.push_back(shared_ptr<Alpha>(new Alpha));
v.push_back(shared_ptr<Alpha>(new Beta));
v.push_back(shared_ptr<Alpha>(new Delta));

v[1]->dosomething(); // still calls Beta's dosomething

您不想拥有Alphas 的向量(而不是Alpha*s,这没关系)的原因是因为 STL 容器会复制您给它们的值,如果您复制 Beta (或Delta)作为Alpha,只会调用Alpha的复制构造函数,并且结果信息必须适合Alpha的大小(如果您已将任何信息添加到子类它不会足够大),并且Beta(或Delta)拥有的额外信息丢失了。这称为切片。

【讨论】:

  • 当我尝试使用 vector 对象时;在我的界面中,Netbeans 告诉我“无法解析标识符向量”......想法?
  • @Jasconius 在您尝试使用vector 之前,请确保您使用#include &lt;vector&gt;using namespace std;using std::vector;
  • 哎呀,好电话...奇怪的是它没有事先要求...一定是一些魔法。好的,一切都很好。谢谢!
【解决方案2】:

最好的方法是将智能指针存储到向量中的类。

你不能按值传递,因为你会得到切片。

如果你通过引用传递,你可能有变量超出范围。

std::vector<shared_ptr<Alpha> > blah;

【讨论】:

    猜你喜欢
    • 2011-07-20
    • 1970-01-01
    • 2012-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-11
    • 2011-11-29
    相关资源
    最近更新 更多