Create an array of objs classes

Consider the following class

class test { public: test(int x){ cout<< "test \n"; } }; 

Now I want to create an array of 50 objects of class test. I cannot change the class test.

Objects can be created on the heap or stack.

Creating objs on the stack is not possible in this case, since we do not have a default constructor in the class

 test objs(1)[50]; /// Error... 

Now we can think of creating objects on a heap like this.

 test ** objs = NULL; objs = (test **) malloc( 50 * sizeof (test *)); for (int i =0; i<50 ; ++ i) { objs[i] = new test(1); } 

I do not want to use malloc. Is there another way?

If you guys can come up with some more solutions, submit them ...

+4
source share
6 answers

You cannot create an array of objects, as in Foo foo [N] , without a default constructor. This is part of the language specification.

Or do:

 test * objs [50]; for() objs[i] = new test(1). 

You do not need malloc (). You can simply declare an array of pointers.

 c++decl> explain int * objs [50] declare objs as array 50 of pointer to int 

But you probably should have some kind of automatic destruction like RAII.


OR publicly:

 class TempTest : public test { public: TempTest() : test(1) {} TempTest(int x) : test(x) {} TempTest(const test & theTest ) : test(theTest) {} TempTest(const TempTest & theTest ) : test(theTest) {} test & operator=( const test & theTest ) { return test::operator=(theTest); } test & operator=( const TempTest & theTest ) { return test::operator=(theTest); } virtual ~TempTest() {} }; 

and then:

 TempTest array[50]; 

You can consider each TempTest object as a test object.

Note: operator = () and the copy constructor are not inherited, so if necessary, follow the appropriate steps.

+7
source

Why do we need an array?

 std::vector<test*> v(50); 

Or like @j_random_hacker suggested in the comments:

 std::vector<test> v(50, test(1)); 

Example:

 /** g++ -Wall -o vector_test *.cpp && vector_test */ #include <algorithm> #include <iostream> #include <iterator> #include <vector> struct Test { int value; Test(int x) : value(x) { std::cout << "Test(" << value << ")" << " "; } operator int() const { std::cout << "int(" << value << ")" << " "; return value; } }; int main() { using namespace std; vector<Test> v(5, Test(1)); cout << endl; copy(v.begin(), v.end(), ostream_iterator<int>(cout, " ")); cout << endl; v[1] = 2; v[2].value = 3; cout << endl; copy(v.begin(), v.end(), ostream_iterator<int>(cout, " ")); cout << endl; return 0; } 

Output:

 Test(1) int(1) 1 int(1) 1 int(1) 1 int(1) 1 int(1) 1 Test(2) int(1) 1 int(2) 2 int(3) 3 int(1) 1 int(1) 1 
+4
source

Unlike many people, you can create an array of objects that do not have a default constructor. What you cannot do is use a set of arguments for all constructor queries. You just need to initialize all its elements. That is, you can do the following:

 #define PRINTT(z, n, initializer) initializer test objs[50] = { BOOST_PP_ENUM(50, PRINTT, 1) // yields 1, 1, 1, .... 1 }; #undef PRINTT 

This will initialize all 50 elements with 1. boost::pp used to automatically print 1 50 times in a row.

+3
source

I think that other respondents consider this question too literally.

If all you really want to do is create a “group” of 50 objects that you can consider as an array, then the easiest and most convenient way for you to accomplish what you are trying to do is:

 std::vector<test> objs(50, test(1)); 

Declares a vector of 50 objects, each of which is a copy of test(1) . A vector is basically an array capable of C ++; although you may not need growth, the fact that it can be called using the 2-arg constructor, which copies each element, is useful here.

You can use it more or less in the same way as an array - for example. The 5th element is objs[4] . The performance is the same - the C ++ standard ensures that inside the elements are stored in an adjacent array.

+2
source

You do not need malloc (). You can also use new for an array of pointers:

  test **objs = new test* [50]; 
0
source

Boost Index Library> A library may come here for salvation. Using boost::ptr_vector<T> you can save a list of objects allocated by a bunch, which can even be polymorphic (virtual functions), which is impossible with a simple std::vector<T> .

Unlike std::vector<T> , objects will not be stored in subsequent memory addresses. However, things like resizing the container will be faster as the elements will retain their original memory addresses. The best bonus is that you do not need to call delete yourself: the contained objects will be destroyed when ptr_vector goes beyond the bounds. Example:

 #include <boost/ptr_vector.hpp> #include <iostream> class test() { protected: int const i; public: explicit test(int i) : i(i) {} virtual void who_am_i() const { std::cout << "I am test " << i << std::endl; } }; class special_test : public test { public: explicit special_test(int i) : test(i) {} virtual void who_am_i() const { std::cout << "I am special_test " << i << std::endl; } }; int main() { boost::ptr_vector<test> objs; for (int i=0; i<50; ++i) objs.push_back(new test(i)); // NB: constructing to heap here! objs.push_back(new special_test(123)); // objs can also hold inherited classes objs[13].who_am_i(); // outputs: I am test 13 objs[50].who_am_i(); // outputs: I am special_test 123 } // all created objects are automatically destroyed here 
0
source

All Articles