B
B
Beard2016-04-21 21:52:35
C++ / C#
Beard, 2016-04-21 21:52:35

How to create dynamic array from class objects?

You need to create a dynamic array of class objects whose only constructor takes a value. C++ without using the vector!
Class description:

class Test {
  int k;
public:
  Test(int _i) {k = _i; }
  ~Test();

  void put_k(int i) {k = i; }
  int get_k() {return k; }
};

Implementation
#define COUNT_OBJ 4
int main()
{
  // Данное объявление массива не является верным, т.к. конструктору класса Test в обязательном порядке нужно передать параметр типа int
  Test *objPtr = new Test[COUNT_OBJ];

  // Со статическим объявлением массива все проще
  Test objArray[COUNT_OBJ] = {5, 6, 7, 8};

  return 0;
}

Answer the question

In order to leave comments, you need to log in

7 answer(s)
B
Beard, 2016-04-22
@mink_h

And so, I found several ways:
2. Implementation of what was said by GavriKos

Test *objPtr = (Test*)calloc(COUNT_OBJ, sizeof(Test));
memset(objPtr, 0, COUNT_OBJ * sizeof(Test));
for (int i = 0; i < COUNT_OBJ; ++i) objPtr[i].put_k(i + 5);

This option should be used with caution as memory is allocated but the object's constructor and destructor are not called.
3. Option provided by Rsa97 in the comments
Test **objPtr = new Test*[COUNT_OBJ];
for (int i = 0; i < COUNT_OBJ; ++i) objPtr[i] = new Test(i + 5);

4. In my opinion, the most successful implementation using Placement new . This method was pointed out by Igor Ivanov
Test *objPtr = static_cast<Test*>(operator new[] (COUNT_OBJ * sizeof(Test)));
for (int i = 0; i < COUNT_OBJ; ++i) new (objPtr + i) Test(i + 5);

I
Ivan Bogachev, 2016-04-21
@sfi0zy

Use vector and don't think about anything

std::vector<Test> myTests(4, Test(777));
std::cout << myTests[0].get_k(); // 777

G
GavriKos, 2016-04-21
@GavriKos

Options:
1) Use a vector
2) Just allocate a piece of memory (malloc and others), and then fill it in a loop
3) Do not use a constructor with a parameter, but make a method of type Initialize.

M
Maxim Moseychuk, 2016-04-21
@fshp

You are only allocating memory. You must initialize manually.

R
Rsa97, 2016-04-21
@Rsa97

Test **objPtr = new (Test *)[COUNT_OBJ];
for (int i = 0; i < COUNT_OBJ; i++)
    objPtr[i] = new Test(i);

A
asapelkin, 2016-04-21
@asapelkin

But what if we make an array not of objects of this class, but an array of pointers to objects? And then in the loop, initialize each element already with a constructor call.
In general, use a vector, what problems.

M
Mercury13, 2016-04-21
@Mercury13

Is there an assignment or move operation? Let even created automatically? If there is, look here.

#include <iostream>
#include <vector>

class Test {
  int k;
public:
  Test(int _i) {k = _i; }

  void put_k(int i) {k = i; }
  int get_k() {return k; }
};


struct TestWrapper {
    Test payload;
    TestWrapper() : payload(0) {}
    TestWrapper(int i) : payload(i) {}
    TestWrapper(const Test& i) : payload(i) {}
};

int main()
{
    Test test(10);
    std::vector<TestWrapper> v;
    v.push_back(test);
    std::cout << v[0].payload.get_k() << std::endl;
    return 0;
}

If not, then a dynamic array cannot work so simply (the trick of a dynamic array is to create a new array and copy information from the old one). Only using smart pointers.
#include <iostream>
#include <vector>
#include <memory>


class Test {
  int k;
public:
  Test(int _i) {k = _i; }
  Test& operator=(const Test&) = delete;
  Test& operator=(Test&&) = delete;

  void put_k(int i) {k = i; }
  int get_k() {return k; }
};


int main()
{
    std::vector<std::unique_ptr<Test>> v;
    v.push_back(std::unique_ptr<Test>(new Test(10)));
    std::cout << v[0]->get_k() << std::endl;
    return 0;
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question