Reputation: 94
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
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
Reputation: 206518
In C++ calling new
does two things:
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