堆中连续分配的对象的动态向量 [英] Dynamic vector of contiguously allocated objects in the Heap

查看:51
本文介绍了堆中连续分配的对象的动态向量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试建立一个类来管理std :: vector< T *>指向必须在堆中连续分配的对象的指针.

I am trying to build a class to manage a std::vector<T*> of pointers to objects that must be contiguously allocated in the heap.

我遇到的问题是,如下所示构建向量会导致非连续分配的对象:

The problem I encountered is that building the vector as shown below leads to non contiguously allocated objects:

std::vector<T*> objects{};
for (size_t i = 0; i < n; i++) objects.push_back(new T());

这是因为 new T()的两个连续执行不必在内存中产生连续的对象.因此解决方案是改用 new [] 运算符,这使我可以实现此实现:

This is because two consecutive executions of new T() do not have to produce contiguous objects in memory. So the solution is to use new[] operator instead, which yielded me to this implementation:

template<class T>
class HeapVector
{
private:
  std::vector<T*> elems_{};
  const size_t BUFFER_SIZE_{}; // Buffer size
  size_t idx_{}; // Index controlling the index local to the buffer.
  T * buffer_ = nullptr; // Buffer

public:
  HeapVector() = default;
  HeapVector(const size_t BUFFER_SIZE = 256) : BUFFER_SIZE_(BUFFER_SIZE) {};


  void emplace_back() // TODO: Should pass constructor parameters or even a constructor
  {
    if (!(elems_.size() % BUFFER_SIZE_))
    {
      idx_ = 0;
      buffer_ = new T[BUFFER_SIZE_];
      elems_.reserve(elems_.size() + BUFFER_SIZE_);
    }
    
    // TODO: Object constructor. Must initialize buffer_[idx]
    // createElement(buffer_[idx], parameters...);
    elems_.push_back(buffer_ + idx_++);
  }

};

通过执行 new T [BUFFER_SIZE _] ,我得到了一个指针,该指针指向使用默认构造函数构建的BUFFER_SIZE_元素连续分配数组的第一个元素.

By executing new T[BUFFER_SIZE_], I get a pointer to the first element of a contigously allocated array of BUFFER_SIZE_ elements built by using the Default Constructor.

我要实现的是,完成此分配后,使用所需的参数/另一个构造函数初始化该对象(请参见TODO).另外,我想避免使用复制构造函数.

What I want to achieve is, after this allocation is done, initialize this object with the desired parameters / another constructor (see TODOs). Also, I would like to avoid Copy Constructors.

鉴于我希望此类成为模板化类,实现此目的的最通用方法是什么?

Given that I want this class to be a templated class, what's the most generic way of achieve this?

推荐答案

使用 std :: vector 作为对象池来存储对象,并使用索引而不是指针来访问对象:

Use a std::vector as object pool to store your objects and use indexes instead of pointers to access the objects:

#include <iostream>
#include <vector>

struct Object {
    std::string name;
    std::size_t age;

    Object(const std::string &n, std::size_t a): name(n), age(a) {}
};

template<typename T>
class Pool;

template<typename T>
class ObjectRef {
    Pool<T> &pool;
    std::size_t index;
    ObjectRef(Pool<T> &p, std::size_t i): pool(p), index(i) {}
public:
    friend Pool<T>;
    T &operator*() {
        return pool.buffer[index];
    }
    T *operator->() {
        return &pool.buffer[index];
    }
};

template<typename T>
class Pool {
    std::vector<T> buffer;
public:
    friend ObjectRef<T>;
    Pool(std::size_t s = 250) {
        buffer.reserve(s);
    }
    
    template<typename... Ts>
    ObjectRef<T> newObject(Ts ...args) {
        buffer.emplace_back(args...);
        return ObjectRef<T>(*this, buffer.size() - 1);
    }
};

int main() {
    Pool<Object> objectPool(250);
    auto objectRef = objectPool.newObject("Name", 30);
    std::cout << objectRef->name;
    Pool<int> intPool(250);
    auto intRef = intPool.newObject(30);
    std::cout << *intRef;
}

这篇关于堆中连续分配的对象的动态向量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆