微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

对象和子类的高效容器

如何解决对象和子类的高效容器

我需要什么

我需要一个容器来存储对象 A 和派生子类 B 的实例。具体来说,我需要实现以下任务:

  • 有效添加新实例(追加就足够了)。
  • 高效地移除容器中随机位置的实例(不需要按索引查找;在迭代容器时会移除对象)。
  • 对容器中的元素进行高效迭代。这是最重要的部分,因为比操作更需要迭代。

示例

文件可能如下所示:

int globalB = 5;

// Base class
class A {
public:
    A(a) : a(a);
    ~A();

    int a;

    virtual int get_b() {
        return globalB;
    }
};

// Derived class
class B : public A {
public:
    B(a,b) : A(a),b(b);
    ~B();

    int a;
    int b;

    int get_b() {
        return b;
    }
};

// Container
class Container {
public:
    Container();
    ~Container();

    // adds an A element
    void add_element(a);

    // adds a B element
    void add_element(a,b);

    // removes all elements with (elem.a == 0)
    void remove_a0_elements();

    // Iterator (I will still have to figure out how this is done properly)
    struct Iterator { /* ... */ };
};


static int example_usage() {

    auto container = Container();
    for (int a=1; i<=100; i++) {
        container.add_element(a);
        container.add_element(a,a);
    }

    int sum = 0;
    for (auto &elem : container) {
        sum += elem.get_b();
    }

    return sum;
}

请注意,与示例所建议的不同,元素不会在连续操作中添加,而是在程序中随机添加。当然,我用来完成示例中的任务的容器的任何结构也都很好(例如,通过移交而不是就地构建来添加元素)。如果有一些内存开销,那不会是主要问题,因为所有对象加在一起并不是很大。

我目前的想法

我想过使用 std::unique_ptr 的向量来完成任务,如建议的 here。但是,我担心内存会以这种方式分散,从而大大降低迭代的性能(参见 here)。另一个想法是让 Container 包装两个向量 - 分别是 AB - 但是我不知道如何构建迭代器。此外,这将使使用更多子类变得困难(我需要它至少适用于两对基类和子类)。

问题

  • 是否有任何标准容器可以满足我的需求?
  • 如果没有,根据需要实现容器的优雅方式是什么?
  • 有没有办法“保留”一块内存来构造 Container 的元素而不知道它们的大小?然后我可以包装一个指针向量并规避内存分散的问题。

解决方法

容器类型和元素存储的选择在这里实际上正交:即使元素单独分配,def histogram_boxplot(feature,figsize=(15,10),bins=None): f,(ax_box,ax_hist)=plt.subplots(nrows=2,sharex=True,gridspec_kw={'height_ratios':(.25,.75)},figsize=figsize) sns.distplot(feature,kde=False,ax=ax_hist,bins=bins) sns.boxplot(feature,ax=ax_box,color='Red') ax_hist.axvline(np.mean(feature),color='g',linestyle='-') ax_hist.axvline(np.median(feature),color='y',linestyle='--') 也不能同时支持高效的删除和迭代 /em>。您当然可以std::vector<std::unique_ptr<A>> 一个元素,但是您必须花时间跳过每次迭代。

可以使用空闲列表来扩充数据结构以允许重用空槽,并使用空槽计数来允许在迭代期间有效地跳过它们。结果是 “colony” data structure(可能作为 reset 包含在 C++23 中)。请注意,它不会追加:新元素以未指定的顺序重用已删除元素的空间。

元素 类型仍有待选择:您可以使用 std::hive,一个类似的自定义类型,它知道 std::variant<A,B> 派生自 B(以便更轻松地为客户提供 A),或者您可以使用单独的容器方法(对排序有其自身的影响)。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。