learning
learning

Reputation: 94

Creating object pointer independent of constructor argument

I am trying to create a vector like container Vector.

Then declared:

Vector< A> Avector.

While allocating memory it gives compilation error that A does not have a default constructor. I wrote the following code to allocate memory.

char *pBuffer = (char*) malloc(size*sizeof(T));
  T *array;
   for(int i = 0; i < size; i++)
  {
    (array+i) = new(pBuffer + i) T;
  }
  return array;

T is a template variable.

The error is due to the fact that in placement new I am using default constructor of T while I have not written a default constructor for A.

I want to know, is there any way so that memory allocation does not depend on constructor signature.

Upvotes: 0

Views: 167

Answers (2)

jogojapan
jogojapan

Reputation: 69967

It's not the memory allocation that depends on the constructor signature. It's the initialization that does.

Even in your example, the allocation is performed by malloc without calling any constructor. It's the initialization (performed by placement-new) that requires the use of a constructor.

There is no way to initialize a user-defined object without calling its constructor.

However, what you can do, at least in C++11, is to put your code into a function that takes the arguments that you need for the constructor as rvalue-references, and passes them on to the constructor call in placement-new. This way it's up to the caller of your function to pass the correct arguments. If no arguments are passed, the default-constructor will be called.

This is in fact the technique used by the emplace-style functions of the new std::vector:

template< class... Args >
void emplace_back( Args&&... args );

It's a variadic template, so any number of arguments (zero or more) are possible. Rvalue-references are used to take them, and inside the implementation you'd have to call the constructor using std::forward to ensure the arguments are passed as-is:

(array+i) = new (pBuffer + i) T(std::forward<Params>(args)...);

So this still requires the use of a constructor, but it leaves it up to the caller to choose the constructor (by choosing the arguments). If no default constructor is available, the caller simply needs to supply the arguments necessary to call a non-default constructor.

Upvotes: 1

Alok Save
Alok Save

Reputation: 206518

In C++ calling new does two things:

  1. Allocates enough memory for the object being created &
  2. Provides oppurtunity to initialize the object properly by calling its constructor.

This is basic design feature of C++ as an language, pt 2 was added conspiciously to overcome malloc behavior of just allocating memory.

In short you cannot change this behavior.

Upvotes: 2

Related Questions