5

Consider a simple class:

class SimpleClass {
    int a;
public:
    SimpleClass():a(0){}
    SimpleClass(int n):a(n){}
    // other functions
};

SimpleClass *p1, *p2;

p1 = new SimpleClass[5];

p2 = new SimpleClass(3);

In this case the default constructor SimpleClass() gets called for the construction of newly allocated objects for p1 and the parameterized constructor for p2. My question is: Is it possible to allocate an array and use the parameterized constructor using the new operator? For example, if I want the array to be initialized with objects having variable a value being 10, 12, 15, ... respectively, is it possible to pass these values when using the new operator?

I know that using stl vector is a better idea to deal with arrays of objects. I want to know whether the above is possible using new to allocate an array.

uba
  • 2,012
  • 18
  • 21
  • 1
    You could use an initializer list, though it doesn't scale all that well. With a vector, it's just a size+value constructor. – chris Mar 11 '13 at 05:58

2 Answers2

7

You could use placement-new as:

typedef std::aligned_storage<sizeof(SimpleClass), 
                             std::alignment_of<SimpleClass>::value
                             >::type storage_type;

//first get the aligned uninitialized memory!
SimpleClass *p1 = reinterpret_cast<SimpleClass*>(new storage_type[N]);

//then use placement new to construct the objects
for(size_t i = 0; i < N ; i++)
     new (p1+i) SimpleClass(i * 10);

In this example, I'm passing (i * 10) to the constructor of SampleClass.

Hope that helps.

Community
  • 1
  • 1
Nawaz
  • 353,942
  • 115
  • 666
  • 851
1

This is one way but it's not exactly what you achieve by new SimpleClass[5] because it creates an array of pointers instead of an array of values:

SimpleClass *p[] = {
    new SimpleClass(10), 
    new SimpleClass(12), 
    new SimpleClass(15)
};

To achieve what you want, I'd recommend code similar to this:

SimpleClass *p2 = new SimpleClass[3];
SimpleClass *pp = p2;
*pp = 10;
*++pp = 12;
*++pp = 15;

It's not ideal because it will create temporary objects on the stack and call assignment operator but it looks clean from the code perspective. Performance is sacrificed here a little bit.

evpo
  • 2,436
  • 16
  • 23
  • It's still very possible with the existing code: `p1 = new SimpleClass[5]{1, 2, 3, 4, 5};` – chris Mar 11 '13 at 06:01
  • Yeah, right. I am actually creating an array of pointers also. – evpo Mar 11 '13 at 06:03
  • 1
    @chris, hang on, your code doesn't compile. error C2143: syntax error : missing ';' before '{' – evpo Mar 11 '13 at 06:09
  • @chris: [No, you cannot do that, not even in C++11](http://stackoverflow.com/questions/7124899/initializer-list-for-dynamic-arrays). – Nawaz Mar 11 '13 at 06:12
  • @evpo, Ah, looks like it's a C++11 feature. It definitely calls the appropriate constructor five times, though. – chris Mar 11 '13 at 06:14
  • @chris: No. It is neither C++11 feature. – Nawaz Mar 11 '13 at 06:15
  • @Nawaz, Looks perfectly fine compiling and doing what it's supposed to, but that's exactly half of what I meant by not scalable, the other half being when the number is known at compile-time, but really big. A vector solves that easily. – chris Mar 11 '13 at 06:16
  • Here's what I mean by it working, by the way: http://liveworkspace.org/code/boTI3%240. I agree it's pretty useless, though. – chris Mar 11 '13 at 06:18
  • @chris: Is that allowed by the Standard? I don't think so. Maybe it is an extension? – Nawaz Mar 11 '13 at 06:20
  • @Nawaz, Oh, maybe. I could have sworn I saw it mentioned somewhere on SO before, but I tried it with Clang and it failed. It makes sense, seeing as how it has no purpose. – chris Mar 11 '13 at 06:21