Object array initialization without default constructor
You can use placement-new like this:
class Car{ int _no;public: Car(int no) : _no(no) { }};int main(){ void *raw_memory = operator new[](NUM_CARS * sizeof(Car)); Car *ptr = static_cast<Car *>(raw_memory); for (int i = 0; i < NUM_CARS; ++i) { new(&ptr[i]) Car(i); } // destruct in inverse order for (int i = NUM_CARS - 1; i >= 0; --i) { ptr[i].~Car(); } operator delete[](raw_memory); return 0;}
Reference from More Effective C++ - Scott Meyers:
Item 4 - Avoid gratuitous default constructors
Nope.
But lo! If you use std::vector<Car>
, like you should be (never ever use new[]
), then you can specify exactly how elements should be constructed*.
*Well sort of. You can specify the value of which to make copies of.
Like this:
#include <iostream>#include <vector>class Car{private: Car(); // if you don't use it, you can just declare it to make it private int _no;public: Car(int no) : _no(no) { // use an initialization list to initialize members, // not the constructor body to assign them } void printNo() { // use whitespace, itmakesthingseasiertoread std::cout << _no << std::endl; }};int main(){ int userInput = 10; // first method: userInput copies of Car(5) std::vector<Car> mycars(userInput, Car(5)); // second method: std::vector<Car> mycars; // empty mycars.reserve(userInput); // optional: reserve the memory upfront for (int i = 0; i < userInput; ++i) mycars.push_back(Car(i)); // ith element is a copy of this // return 0 is implicit on main's with no return statement, // useful for snippets and short code samples}
With the additional function:
void printCarNumbers(Car *cars, int length){ for(int i = 0; i < length; i++) // whitespace! :) std::cout << cars[i].printNo();}int main(){ // ... printCarNumbers(&mycars[0], mycars.size());}
Note printCarNumbers
really should be designed differently, to accept two iterators denoting a range.
You can create an array of pointers.
Car** mycars = new Car*[userInput];for (int i=0; i<userInput; i++){ mycars[i] = new Car(...);}...for (int i=0; i<userInput; i++){ delete mycars[i];}delete [] mycars;
or
Car() constructor does not need to be public. Add a static method to your class that builds an array:
static Car* makeArray(int length){ return new Car[length];}