在没有调用构造函数的对象数组中分配内存?

时间:2013-04-15 19:13:36

标签: c++ arrays

我想创建一个简单的模板arraylist类,但是当我执行类似

的操作时
T* typeArray = new T[10];

这会创建10个对象实例,调用构造函数10次。我怎样才能创建一个空数组,以后我可以放置对象?

2 个答案:

答案 0 :(得分:5)

这不是用C ++做事的首选方式,但是

T* my_array = (T*)malloc(10 * sizeof(T));

更符合标准C ++实践的解决方案是

std::vector<T> my_vector;
my_vector.reserve(10);

注意(正如评论中所提到的)reserve的解决方案的不同之处在于,如果没有进一步的操作,my_vector[5]无效,而my_array[5]则无效。随后您需要my_vector.resize(10)之类的东西来索引它,这将构建所有10个项目。您可以通过push_back(T const&)emplace_back(Args...&& args)从前到后构建它们。只有在构造这种方式之后才[]索引合法。作为警告,[]索引即使在非法时也可能有效,但它是未定义的行为。

答案 1 :(得分:3)

template<typename T>
struct RawMem {
  alignas(T) unsigned char data[sizeof(T)];
  T& get_unsafe() { return *reinterpret_cast<T*>(&data[0]); }
  T const& get_unsafe() const { return *reinterpret_cast<T const*>(&data[0]); }
  template<typename... Args>
  void Construct( Args&&... args ) {
    new (&data[0]) T( std::forward<Args>(args)... );
  }
  void Destroy() {
    get_unsafe().~T();
  }
};

RawMem<std::string>* buff = new RawMem<std::string>[10];
for (int i = 0; i < 10; ++i) {
  buff[i].Construct( "bob is your uncle" );
}
for (int i = 0; i < 10; ++i) {
  std::cout << buff[i].get_unsafe() << "\n";
}
for (int i = 0; i < 10; ++i) {
  buff[i].Destroy();
}
delete buff;

请注意,在调用析构函数时,您完全负责处理,如果不是,则使用上述模式。

我添加了帮助ConstructDestroy功能,因此您不必自行处理展示位置new等问题。同样,get_unsafe()会让您在需要时获得T&个实例。

以上使用C ++ 11 alignas,因为在C ++ 03中无法解决问题。