0

我想创建一个简单的模板数组列表类但是当我做类似的事情时

T* typeArray = new T[10];

这会创建 10 个对象实例,调用构造函数 10 次。如果我以后可以放置对象,我该如何创建一个空数组?

4

2 回答 2

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)。只有以这种方式构建后,[]索引才是合法的。作为警告,[]即使是非法的,索引也可能起作用,但它是未定义的行为。

于 2013-04-15T19:14:53.057 回答
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 中没有办法解决这个问题。

于 2013-04-15T19:33:59.223 回答