4

The dynamically created array of objects need to use a non-default constructor, and the problem I'm running into I think is the syntax. In my mind, the fact that I'm able to do this

int * somePtr = new int[5];

means that I should be able to do this

IntegerSet* someSet = new IntegerSet(this->getLength())[5];

where IntegerSet is a class I have made that represents an integer set. this code is happening inside one of IntegerSets member function. When I try this I get a syntax error "cannot convert from IntegerSet to IntegerSet*"

I understand what this means, the two types aren't equivalent, but I can't see the difference between doing what I did in part 1 and part 2, besides the fact that part 2 has to have an argument list passed as the constructor. So it is in that part of the code that I suspect I have the syntax wrong

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
JohnA
  • 157
  • 2
  • 13
  • 1
    It always used to be the case that you couldn't do this, either you had to have a default constructor so you could dynamically allocate an array of your objects, or you had to use placement new to separate allocation from construction. This has probably changed with C++11. Which version of C++ are you using? – john Sep 25 '13 at 06:01
  • 1
    in c++ it is more convenient to use the std::vector instead of dynamic arrays (because it is more handy), you could have a look hat [this Tutorial](http://www.dreamincode.net/forums/topic/33631-c-vector-tutorial/) – Martin Sep 25 '13 at 06:02
  • @john I am using C++11 using Visual Studio 2012 professional version. The thing is I need to dynamically allocate an array to hold the members of the set and the length of this array is based on what the user says the size of the set is, so I can't see a way to allocate the array of IntegerSets without having the default constructor called which would mean the user couldn't pass in a variable length – JohnA Sep 25 '13 at 06:05
  • that sounds exactly like you would be happy with vectors ;) – Martin Sep 25 '13 at 06:06
  • @Martin I would definitely like to use vectors, I tend to use them a lot, but it's for class and right now we are going over dynamically memory allocation. This specific task is not required, (I asked my teacher about the syntax and she didn't know either), but I am trying to add some additional functionality to make the class more fun – JohnA Sep 25 '13 at 06:07
  • the problem is: `int` is a type, `new IntegerSet(this->getLength())` is not. Array creation only works with types. Anything else gets treated as element access. – thriqon Sep 25 '13 at 06:10

2 Answers2

3

new expression allows only default initialization, you can not do this within single new expression. What you could do is allocate raw memory and construct objects one by one using placement new (see this answer in Object array initialization without default constructor)

Or yet even better, don't use C-style arrays. Instead, use some STL container such as std::vector and it's constructor, where the 2nd argument is a value that will be used to initialize elements:

std::vector<IntegerSet> integers(5, IntegerSet(this->getLength()) );
Community
  • 1
  • 1
LihO
  • 41,190
  • 11
  • 99
  • 167
  • no, because then the array of Integersets get created with the default constructor called. I am passing this->getLength() as the argument to the constructor I have created, this allow the Integersets I'm creating to be the same length as the Integerset whose member function this is being called from – JohnA Sep 25 '13 at 05:59
  • He says at the start of the question 'The dynamically created array of objects need to use a non-default constructor' – john Sep 25 '13 at 05:59
  • @user2813824: Sorry, I misread the question first time. See my edit. – LihO Sep 25 '13 at 06:08
  • @Liho, thanks for the link and for helping out. Now that I know it's not possible I'll just use a vector, this function isn't required for the project but I wanted to add some functionality that really pushed dynamic object allocation to the limits. Vectors will have to do! – JohnA Sep 25 '13 at 06:10
0

There is an easy way out of this problem: add a default constructor to IntegerSet that does not acquire memory and any other resources. This way you can allocate an array of IntegerSet with new and then fill each element of the array on the next step.

Even better solution: use std::vector<IntegerSet> and emplace_back() to initialize each element of the array using a non-default constructor.

Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271