5

Assume a class X with a constructor function X(int a, int b)

I create a pointer to X as X *ptr; to allocate memory dynamically for the class.

Now to create an array of object of class X

 ptr = new X[sizeOfArray];

until now everything is fine. But what I want to do is creation of the above array of objects should invoke the constructor function X(int a, int b). I tried as follows:

ptr = new X(1,2)[sizeOfArray]; 

As expected It gave me compile time error

error: expected ';' before '[' token|

How can I create an array of objects to invoke the constructor?

SizeOfArray is entered by the user at runtime.

EDIT: What I wanted to achieve in not possible as answered by zenith or will be too complex . So how can I use std::vector for the same?

Pushkar
  • 760
  • 15
  • 37

3 Answers3

5

This seems like a job for placement new...

Here's a basic example:

Run It Online !

#include <iostream>
#include <cstddef>  // size_t
#include <new>      // placement new

using std::cout;
using std::endl;

struct X
{
    X(int a_, int b_) : a{a_}, b{b_} {}
    int a;
    int b;
};

int main()
{
    const size_t element_size   = sizeof(X);
    const size_t element_count  = 10;

    // memory where new objects are going to be placed
    char* memory = new char[element_count * element_size];

    // next insertion index
    size_t insertion_index = 0;

    // construct a new X in the address (place + insertion_index)
    void* place = memory + insertion_index;
    X* x = new(place) X(1, 2);
    // advance the insertion index
    insertion_index += element_size;

    // check out the new object
    cout << "x(" << x->a << ", " << x->b << ")" << endl;

    // explicit object destruction
    x->~X();

    // free the memory
    delete[] memory;
}

EDIT: If I've understood your edit, you want to do something like this:

Run It Online !

#include <vector>
// init a vector of `element_count x X(1, 2)`
std::vector<X> vec(element_count, X(1, 2));

// you can still get a raw pointer to the array as such
X* ptr1 = &vec[0];
X* ptr2 = vec.data();  // C++11
maddouri
  • 3,737
  • 5
  • 29
  • 51
  • `std::aligned_storage` may help. But `std::vector` is simpler. – Jarod42 Oct 22 '15 at 15:19
  • `std::aligned_storage` is certainly interesting. As of `std::vector`, the OP is required not to use it. Besides, I think [`std::vector` does use placement new](https://en.wikipedia.org/wiki/Placement_syntax#Default_placement). – maddouri Oct 22 '15 at 15:22
  • see edit. I might try `std::vector` since this seems too complex to follow – Pushkar Oct 22 '15 at 15:25
  • I am allocating the memory by a setter function the class. Will the data remain in memory after the function returns? – Pushkar Oct 22 '15 at 15:53
  • @OP unless you provide actual code snippets for what you did, I'm afraid that I won't be able to give you a relevant answer. – maddouri Oct 22 '15 at 18:26
4

This is not possible in the current C++ standard, unless:

  • you provide an initializer for each element, or
  • you use a vector.

See:

Community
  • 1
  • 1
Emil Laine
  • 41,598
  • 9
  • 101
  • 157
1

You don't say if sizeOfArray is a variable or a constant. If it is a (small) constant, you can do this in C++11:

X* ptr = new X[3] { {1,2}, {1,2}, {1,2} };
oz1cz
  • 5,504
  • 6
  • 38
  • 58