user1567909
user1567909

Reputation: 1480

creating 2-d array of objects with a constructor with a parameter

I'm trying to create a 2-d array of objects. I'm trying to set the constructor of the class I made equal to a constructor that will take in a parameter. However, I keep getting an error saying:

main.cpp:18:37: error: invalid user-defined conversion from 'test*' to 'const test&'

int main()
{
  test arr[9][9];
  char s[9][9];
  int integerArray[9][9];
  for(unsigned int i = 0; i < 9; i++)
  {
    for(unsigned int j = 0; j < 9; j++)
    {
      cin >> s[i][j];
      arr[9][9] = new test(s[i][j]);
    }
  }
  return 0;
}

With test being the class. Can anyone help me figure out this error? I understand that the new function returns a void pointer but how can I get it so that my 2d array takes in the parameter?

Thanks.

Upvotes: 3

Views: 1530

Answers (4)

scones
scones

Reputation: 3345

Within you code you basically have a type mismatch, since you try to assign a pointer to X to an X. I assume this happens, because you try to assign a test, but test has no default constructor.

An easier solution, that avoids a default constructor, but has some overhead with copy construction, would be to use a vector with a given constructor.

std::vector<std::vector<test, test(char(0))> > arr;
char a(0);
for (unsigned int i = 0; i < 9; ++i) {
  for (unsigned int j = 0; j < 9; ++j) {
    std::cin >> a;
    arr[i][j] = test(a);
  }
}

Upvotes: 0

js2016
js2016

Reputation: 1

//Class with one arg constructor/no default constructor whose 2d array need to be // allocated on heap using new

class A
{
    public:

        A(int i):m_i(i)
        {
            cout<<"constructor called i="<<i<<endl;
        }
        ~A()
        {
            cout<<"destructor called i="<<m_i<<endl;
        }
        int get()
        {
            return m_i;
        }
        friend ostream& operator<<(ostream& os, const A& obj);
    private:
        int m_i;
};

ostream& operator<<(ostream& os, const A& obj)
{
    os<<obj.m_i;
    return os;
}


typedef unsigned char Byte;
int main()
{
    int m=4;
    int n=3;
    int s[4][3] = { {1,2,3},
                    {4,5,6},
                    {7,8,9},
                    {10,11,12}
                  };

//Allocate a buffer to hold the array, on heap
    Byte* pBuff = new Byte[sizeof(A)*m*n];
    for(int i=0;i<m;++i)
    {
        for(int j=0;j<n;++j)
        {
             A* p = new (pBuff+sizeof(A)*(n*i+j)) A(s[i][j]);
        }
    }

//Accessing array 
    A (*testArr)[3] = (A (*)[3])pBuff;
    for(int i=0;i<4;++i)
    {
        for(int j=0;j<3;++j)
        {
            cout<<"testArr["<<i<<"]["<<j<<"]="<<testArr[i][j]<<endl;
        }
    }
    //after you are done with the array of objects.
    for(int i=0;i<m;++i)
    {
        for(int j=0;j<n;++j)
        {
             A* p=(A*)(pBuff+sizeof(A)*(i*n+j));
             p->~A(); //call destructor for each object.

        }
    }
    delete[] pBuff; //Delete the buffer.
    return 0;
}

Upvotes: 0

v154c1
v154c1

Reputation: 1698

When you declare the array as test arr[9][9]; then the memory is allocated and default constructor is called for each member. So you don't need call new to allocate new memory. I assume that you goal is to have array of test objects constructed with the value read from std::cin.

Then you have several options:

  • Easiest solution is to use 2D array of pointers:

It would look like:

test* arr[9][9];
for(unsigned int i = 0; i < 9; i++)
{
  for(unsigned int j = 0; j < 9; j++)
  {
     cin >> s[i][j];
     arr[i][j] = new test(s[i][j]);
  }
}
  • If you want to keep the array of plain test objects (without pointers), the use can either:

Provide a test::set(int) method to set the value after is was constructed.

test arr[9][9];
for(unsigned int i = 0; i < 9; i++)
{
  for(unsigned int j = 0; j < 9; j++)
  {
     cin >> s[i][j];
     arr[i][j].set(s[i][j]);
  }
}

Construct temporarily object and then assign it to your already allocated one in the array using operator=(const test&) (or operator=(test &&) in c++11). Note that there's no new here:

test arr[9][9];
for(unsigned int i = 0; i < 9; i++)
{
  for(unsigned int j = 0; j < 9; j++)
  {
     cin >> s[i][j];
     arr[i][j] = test(s[i][j]);
  }
}

Or use placement new (this constructs new object in the pre-allocated memory block):

test arr[9][9];
for(unsigned int i = 0; i < 9; i++)
{
  for(unsigned int j = 0; j < 9; j++)
  {
     cin >> s[i][j];
     new(&arr[i][j]) test(s[i][j]);
  }
}
  • And last one: If you don't have specific reason to use static 2D array, go for some STL container.

Upvotes: 0

Lews Therin
Lews Therin

Reputation: 10995

Your 2d array is not an array of pointers to a test object. Memory is allocated for your 2d array anyway. So no need for the loop.

Unless you change your declaration

test arr[9][9];

to something like:

 test*** arr = new (test**)[rows];


  for(unsigned int i = 0; i < 9; i++)
    {
      for(unsigned int j = 0; j < 9; j++)
      {
         cin >> s[i][j];
         arr[i][j] = new test(s[i][j]);
      }
     }

Upvotes: 2

Related Questions