Reputation: 1480
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
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
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
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:
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]);
}
}
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]);
}
}
Upvotes: 0
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