I want to create a simple template arraylist class but when i do something like
T* typeArray = new T[10];
this creates 10 instances of the object, calling the constructor 10 times. How can i create an empty array were i can later place objects?
It's not the preferred way of doing things in C++, but
T* my_array = (T*)malloc(10 * sizeof(T));
A solution more in line with standard C++ practice is
std::vector<T> my_vector;
my_vector.reserve(10);
Note, (as alluded to in comments) the solution with reserve differs in that without further action my_vector[5] is not valid whereas my_array[5] is. You will subsequently need something like my_vector.resize(10) in order to index it, which will construct all 10 items. You can construct them front-to-back by doing push_back(T const&) or emplace_back(Args...&& args). Only after constructed this way is [] indexing legal. As a warning, [] indexing may work even when illegal, but it is undefined behavior.
std::array will cause constructor calls. +1 for the vector answer.vector? Because there is a right and wrong answer just hanging there....my_vector[0], which is undefined behavior that will sometimes work, misleading the OP into thinking that they did nothing wrong. :) I just think you should mention what to do with your my_vector once you reserve!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;
note that you are completely in charge of handling when the destructor is called, and when it isn't, with the above pattern.
I included helper Construct and Destroy functions so you don't have to mess around with placement new and the like yourself. Similarly, get_unsafe() will let you get ahold of the T& instance when you want it.
The above uses C++11 alignas, because there is no way in C++03 to solve the problem.
unique_ptr, but not at the array of manually constructed objects with no state that describes which is constructed and which not?RawMem might accomplish something useful in some limited cases. There's no reason at all for having a manual delete in new code (unless writing an RAII class itself). Of course, some form of state should go into RawMem in order to ensure the contained T gets destroyed...
std::shared_ptrorstd::unique_ptrinstances instead so that deallocating the thing causes delete to be called on the underlying bits automatically. Of course, it is likely that doing all those allocations would be far more expensive than just calling constructors.charand then use placement new to construct objects in the chunks. When doing this you need to be careful about alignment.