我想创建一个简单的模板arraylist类,但是当我执行类似
的操作时T* typeArray = new T[10];
这会创建10个对象实例,调用构造函数10次。我怎样才能创建一个空数组,以后我可以放置对象?
答案 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;
请注意,在调用析构函数时,您完全负责处理,如果不是,则使用上述模式。
我添加了帮助Construct
和Destroy
功能,因此您不必自行处理展示位置new
等问题。同样,get_unsafe()
会让您在需要时获得T&
个实例。
以上使用C ++ 11 alignas
,因为在C ++ 03中无法解决问题。