is there a way to override the new[] to control how the constructor is called?
for example give a class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
class foo
{
private:
int a, b;
public:
foo() : a(1), b(1) {}
~foo() {}
};
int main(int argc, char* argv[])
{
foo* x;
x = new foo[10000]; // first allocate memory then change how the constructor called through a loop
delete [] x;
return 0;
}
I don think that the placement new is the right approach. I know that during the code x = new foo[10000];
Two operations occur.
First the code allocates at least enough memory for 10000 foo objects.
Next the code constructs 10000 foo objects.
What I would like to modify is the second part.
Yes
placement new from what I saw is just putting data into a buffer. I do not want a buffer, and I do not want change the memory model. All I want is to change when and what new [] operator calls the constructor.
the code below is only to demonstrate my purpose.
1 2 3 4 5 6 7 8 9
class foo
{
private:
int a, b;
public:
foo() : a(1), b(1) {}
foo(int i) : a(i), b(0) {}
~foo() {}
};
x = new foo[10000];//where foo[] might call foo(i) where i is a position of the foo object
If you don't want to store your objects in a buffer, then unfortunately you have no options. The only way to get what you want is to use placement new, or an array of pointers.
Yes
placement new from what I saw is just putting data into a buffer.
Placement new constructs an object at an existing memory location. It does not "put data into a buffer." If you want to divorce the construction of an object from the allocation of memory for an object as you seem to want to do, you must use placement new.
Your example is not complete. There is no sense of where you want a constructor to be called or how the array would be accessed. placement new is usually used in the context of a container, but that doesn't appear to be what you're doing.
I think that your code is closer to what I want. The only problem is that in the class I would have to create another class to create the array and prevent people from calling the new [] and delete [] operators on the foo class. is there a way to override the construction call in the new [] operator and the destruction call in the delete [] operator.
... to control how the constructor is called?
for example give a class
Can you elaborate on what you're trying to do? What do you want to change about the way the constructor is called? Change the order in which the array items are initialized? Use different constructors for different items in the array? Something else?
is there a way to override the construction call in the new [] operator and the destruction call in the delete [] operator.
No, because you're confusing a few different things. There is "operator new" which only allocates memory, "placement new" which only calls constructors, and just plain "new" which does both. It is only possible to change the behavior of "operator new", but you want to change the behavior of "new".
I don't know what you are trying to do if you expect yourself to create the objects and others to clean them up. It makes no sense.
where the second operation is what I need to override how should I override this code
What I want to do is to construct 10,000 foo objects in parallel though an array.
I am now worried about the parallel part just I what to knows how to change the loop when constructing objects
The expression new foo[10000] calls only one allocation function: void* operatornew[] (std::size_t) (static member of foo if provided, global otherwise: note that your non-static member would never be called). Then it calls foo::foo() 10000 times, directly, with no other functions involved.
how to change the loop when constructing objects
don't use new, that's how std::vector and other containers do it.
I think that I should try to create a class like foobar to control the creation and destruction of foo objects and delete the void* opertator new [] (std::size_t)
I believe that it does prevent anyone from calling the code x = new foo[10000]; where x is a foo pointer. This code might be C++ 14 or C++ 11 code and might not compatible with older C++ compliers.
can I prevent it from calling foo::foo() 10000 times
Ah. Now we're getting somewhere. :)
So does this mean that you're okay with having the data in foo be uninitialized? If so then you could just not define a default constructor.
If class foo has a base class or class member data, then do they have default constructors? If so then you can't get away from the problem.
If foo has virtual functions then you must call the constructor.
If you don't construct the foo objects then what happens when they are destroyed? Will the destructor work? Will your solution even call the destructor?
For all of these reasons I think you may want to step back and reevaluate what you're trying to do. Do you really need to construct 10,000 foos? At that time? If so then you should let the constructor be called. Would a vector<foo> be more appropriate?
I have found that I can initialized the data in the void *operatornew[](size_t t) but in doing so it recalls the constructors after the data has been allocated.
During my experiments using Visual C++ Express 2013 for desktop I found that t is the number of foo objects needed time the sizeof(foo) plus 4. I think that the 4 is there for telling how many objects are allocated for the array.
The purpose of this exercise is to find a way to initialize 10,000+ foo objects using a parallel process such as C++ AMP, OpenMP, Threading Building Blocks, or Microsoft's Parallel Patterns Library.
foo does not have any inheritance and so therefore no virtual functions and no base constructor
vector<foo> would not be ideal is this case because I do not have control of the construction objects. Also, this does not change once it is written. However if you are suggesting to still go with vector<foo> then I think writing a templated array class might be the best solution.