When i define dynamic array of objects, i want to choose one parameterized constructor for all objects in my array. without having to write for each object the chosen constructor like this
#include <iostream>
using namespace std;
class foo {
public:
foo ()
{
cout << "default constructor" << endl;
}
foo (int x)
{
cout << "parameterized constructor " << endl;
}
~foo ()
{
cout << "destructor" << endl;
}
};
int main (void)
{
int size = 3, parameter = 10;
foo *array;
array = new foo [size] { foo(parameter), foo(parameter), foo(parameter) };
cout << endl;
delete [] array;
return 0;
}
output
parameterized constructor
parameterized constructor
parameterized constructor
destructor
destructor
destructor
So, as you can see from the above code, I can choose parameterized constructor for each object in my array array = new foo [size] { foo(parameter), foo(parameter), foo(parameter) };
. However, if user inputs the size
. same trick won't work
When I searched for solution, I found that I can do it with copy constructor like this
#include <iostream>
using namespace std;
class foo {
public:
foo ()
{
cout << "default constructor" << endl;
}
foo (int x)
{
cout << "parameterized constructor " << endl;
}
~foo ()
{
cout << "destructor" << endl;
}
};
int main (void)
{
int size = 3, parameter = 10;
foo *array;
array = new foo [size];
cout << endl;
for (int i = 0; i < size; i++)
array[i] = foo(parameter);
cout << endl;
delete [] array;
return 0;
}
output
default constructor
default constructor
default constructor
parameterized constructor
destructor
parameterized constructor
destructor
parameterized constructor
destructor
destructor
destructor
destructor
However, destructors are called for each object, and i don't want this i just want to do it while allocating for the first time
Thanks in advance, and I hope that there's a solution.
The simplest solution to this problem would be to use std::vector
which handles all those problems internally, eg:
#include <vector>
// skipping class declaration for brevity
int main (void)
{
int size = 3, parameter = 10;
std::vector<foo> array;
array.reserve(size);
cout << endl;
for (int i = 0; i < size; i++)
array.emplace_back(parameter);
cout << endl;
return 0;
}
However, if for some reason you want/need to do this by hand then you should be allocating a "raw buffer" and construct objects inside that buffer with placement new
- this will however also require you to manually call the destructors
One possible example, doing everything "manually" could look like this
int main (void)
{
int size = 3, parameter = 10;
foo *array = reinterpret_cast<foo*>(new char[size * sizeof(foo)]);
cout << endl;
for (int i = 0; i < size; i++)
new (&array[i]) foo(parameter);
cout << endl;
for (int i = 0; i < size; i++)
array[i].~foo();
delete[] reinterpret_cast<char*>(array);
return 0;
}
An arguably cleaner solution is to use std::allocator
and std::allocator_traits
- this would look like this
#include <memory>
// skipping class declaration
int main (void)
{
std::allocator<foo> alloc;
using alloc_t = std::allocator_traits<decltype(alloc)>;
int size = 3, parameter = 10;
foo *array;
array = alloc_t::allocate(alloc, size);
cout << endl;
for (int i = 0; i < size; i++)
alloc_t::construct(alloc, &array[i], parameter);
cout << endl;
for (int i = 0; i < size; i++)
alloc_t::destroy(alloc, &array[i]);
alloc_t::deallocate(alloc, array, size);
return 0;
}
I would use a for
loop:
array = new foo [size];
for(int i = 0; i < size; i++) {
array[i] = foo(parameter);
}
I don't see a simpler way to do it. And with this method, your size
can be parametrized easily.
For your "destructor issue", use pointer on foo:
array = new *foo[size];
for(int i = 0; i < size; i++) {
array[i] = new foo(parameter);
}
But do not forget to delete each foo
instance when needed:
for(int i = 0; i < size i++) {
delete array[i];
}
delete[] array;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.