Interview Question
Software Engineer / DevelopersThis solution is good only when you know what you need in that array at compile time. Assume that the content of the array should be detected at run time.
what do you mean by "content of the array should be detected at run time"? If you mean objects should be created at run time then use array of pointers(much better option will be to use vector<class*> )....
Here the length of the array and exact arguments of constructors are known at compile time. Suppose that you need to read the length and each argument from console. The elements will be allocated in sequential cells (in case of using array of pointers, the actual objects allocated in different locations).
Use placement new
To Create array of data type A, do the following
void *mem = ::operator new(sizeof(A) * numOfArrElems);
A *a = static_cast<A*>(mem);
for(int i = 0; i < numOfArrElems; ++i) {
new (a[i]) A(args);
}
// Do your stuff....
// Call dtors on all elems and then delete the memory in the same fashion as was
// allocated
for(int i = 0; i < numOfArrElems; ++i) {
a[i].~A();
}
::operator delete((void*)a);
I really dont understand how this would prevent the default constructor from getting called?/
The question is not on how to prevent the default ctor to get called, but to create an array of objects of a class which doesn't provide default ctor, when you declare an array - e.g. A a[20] - the default ctor is called for all the 20 objects in array, but if the class doesn't provide one, u need to use a loop to call ctor of all the objects of array.
Dipkin,
Can you explain what you are doing in line
new (a[i]) A(args);?
As per your allocation of sizeof(A)*nomOffArrElem,
a[i] is the starting address of a block of memory as large as sizeof(A) and not the start address of a block of memory as large as 4 bytes (pointer to A).
So space allocation is already done.
Should the line
void *mem = ::operator new(sizeof(A) * numOfArrElems);
not be changed to
void **mem = ::operator new(sizeof(A*) * numOfArrElems);
and other changes accordingly?
How abt making the default constructor for that particular class private and use default arguments in some constructor??
You have to define an array of pointers. Then you can initialize each pointer separately by using "new":
C* ptrArray[10];
ptrArray[0]=new C(22);
ptrArray[1]=new C(4);
...
This is from "Effective C++" by Scott Meyers. He has another book "More Effective C++". In BB they always ask questions from these books.
This will lead to compiler error
class A
{
A(int i):x(i) {}
private:
int x;
};
int main(int argc, char *argv[])
{
A array[10];
system("PAUSE");
return EXIT_SUCCESS;
}
Reason: no default constructor..
--------------------------------------
one best way to get aroung it is
class A
{
A(int i):x(i) {}
private:
int x;
};
int main(int argc, char *argv[])
{
A* array[10];
system("PAUSE");
return EXIT_SUCCESS;
}
Maintain an array of pointers so that constructors never have to be called
for every array element write which constructor to be called.
- tito June 20, 2010Eg. A a[] = {A(1,2), A(), A(1) }, where A(1,2), A(), A(1) are constructor available for class A.