Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't one dynamically declare an array of objects in C++ like this :

In my C++ project, there is a class which needs to create an array of objects. Between different instances of the class, the size of the array will be different, which is why I chose to use an array.

If I do :

int numberOfPlayers; // This is determined at run time.
int *players; 

//In constructor
players= new int[numberOfPlayers]; // This works

But if I do:

Character *players;
players = new Character[numberOfPlayers]; // Compiler complains

The Compiler complains "No matching constructor for initialisation of Character"

How do I dynamically declare an array of type "Character".

Note: Character has nothing to do with char. Character is a name of an class I created myself.

EDIT: Character does not have a default constructor, since it needs to be passed several arguments so it can be initialised with the proper state. The only constructor is has takes several arguments.

EDIT: I chose a dynamically created array, over a vector since I know during the lifetime of the instance, the size of the array will be constant, though between different instances the size will be different. I thought this would make sense for performance reasons (memory / speed).

like image 955
Rahul Iyer Avatar asked Jun 17 '14 03:06

Rahul Iyer


People also ask

Can you dynamically create an array in C?

We can create an array of pointers also dynamically using a double pointer. Once we have an array pointers allocated dynamically, we can dynamically allocate memory and for every row like method 2.

Can we declare array dynamically?

A simple dynamic array can be constructed by allocating an array of fixed-size, typically larger than the number of elements immediately required.

How do you declare a dynamic array of objects in C++?

To make a dynamic array that stores any values, we can turn the class into a template: template <class T> class Dynarray { private: T *pa; int length; int nextIndex; public: Dynarray(); ~Dynarray(); T& operator[](int index); void add(int val); int size(); };


3 Answers

The "proper" way is to use std::vector. It is a fast, safe, more robust alternative to horrible new.

std::vector<Character> vec;
vec.push_back(Character(params));
vec.push_back(Character(other_params));

If you know the size ahead, you can avoid reallocation overhead by using std::vector::reserve

std::vector<Character> vec;
vec.reserve(50);
vec.push_back(Character(params));
vec.push_back(Character(other_params));

The overhead of std::vector is practically non-existent.

Now, the reason why you can't do this your way, it's because by default new uses default constructor, and it doesn't exist.

like image 131
milleniumbug Avatar answered Sep 18 '22 03:09

milleniumbug


The problem is that your type Character does not define a default constructor of the form:

Character::Character()
{
   // etc.
}
like image 41
Keith Avatar answered Sep 20 '22 03:09

Keith


Your type needs a default constructor. Unlike C's malloc, operator new constructs instances for you at the time of allocation. It then follows that it requires a parameterless (default) constructor as it provides no way to pass arguments. So...

class Character
{
public:
    Character(){}
};
like image 21
Ed S. Avatar answered Sep 19 '22 03:09

Ed S.