May 30, 2012 at 12:19am May 30, 2012 at 12:19am UTC
Hello,
I believe that I have some sort of circular inclusion error in my code, and the error I am getting is:
field 'm_advArray1' has incomplete type
This is my code. As you can see, I try to compose my MainClass of another class PieceClass1.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
#ifndef COMPOSITIONCLASSES_H
#define COMPOSITIONCLASSES_H
#include <iostream>
using namespace std;
class PieceClass1;
class MainClass
{
private :
int m_value1;
const int m_value2;
int * m_nPntr1;
PieceClass1 m_advArray1;
public :
MainClass(int arg_m_value);
~MainClass();
};
MainClass::MainClass(int arg_m_value = 0): m_value1(arg_m_value), m_value2(arg_m_value), m_nPntr1(0)
{
}
MainClass::~MainClass()
{
delete m_nPntr1;
}
/////////////////////////////////////////////////////
class PieceClass1
{
private :
int array1[5];
public :
PieceClass1(int startingValue = 0);
friend ostream& operator <<(ostream&, const PieceClass1&);
};
PieceClass1::PieceClass1(int startingValue)
{
for (int i = 0; i < 5; ++i)
{
array1[i] = startingValue;
}
}
ostream& PieceClass1::operator <<(ostream& output, const PieceClass1& inputClass)
{
for (int i = 0; i < 5; ++i)
{
output << inputClass.array1[i] << "\n" ;
}
}
#endif // COMPOSITIONCLASSES_H
Thanks,
Flurite
Last edited on May 30, 2012 at 12:20am May 30, 2012 at 12:20am UTC
May 30, 2012 at 12:29am May 30, 2012 at 12:29am UTC
In order to create a class instance like that, the compiler needs the full definition of the class so it knows how large it needs to be.
Move the definition to where you have the declaration and it should work.
May 30, 2012 at 12:39am May 30, 2012 at 12:39am UTC
@firedraco,
That would work if only one incorporated the other, which is what I am doing in that case. But how would I do it if both incorporated each other?
May 30, 2012 at 2:04am May 30, 2012 at 2:04am UTC
They can't.
This box has our universe inside it
There is no 1 to 1 relationship. They would be the same thing in that case.
However, you could maintain a reference only needing a forward declaration.
May 30, 2012 at 10:52am May 30, 2012 at 10:52am UTC
@ne555,
Ahh, I see. Just out of curiosity, why would references be a safe way to kind of "bypass" a class prototype?
May 30, 2012 at 9:02pm May 30, 2012 at 9:02pm UTC
The compiler doesn't need to know the size of the class to make a reference to it.
May 30, 2012 at 10:15pm May 30, 2012 at 10:15pm UTC
Why does the size of the class matter?
May 30, 2012 at 10:38pm May 30, 2012 at 10:38pm UTC
Because a class, among other things, contains all the data inside of itself. So when you say it contains a PieceClass1, the compiler needs to put an entire PieceClass1 inside there, which it can't do if it doesn't have the definition. If you use a reference, it only needs to store a reference, which is independent of the class definition itself.
May 30, 2012 at 11:00pm May 30, 2012 at 11:00pm UTC
@Zhuge,
Okay, I see. The compiler only checks whether the data type its referencing to exists. Otherwise, it does not check anything else.
Thanks everyone for the help so far!
However, there is no way to initialize it, besides using pointers. I guess one-way composition is the only way to go.
Last edited on May 30, 2012 at 11:23pm May 30, 2012 at 11:23pm UTC
May 31, 2012 at 12:12am May 31, 2012 at 12:12am UTC
Using pointers isn't so bad. It has all kinds of advantages, from late binding of that member to reducing the size of header files.
It's easy to forget how bloated C++ header can become until you go back and compile a C program on the same kit. 10 times faster compilation is not uncommon.
Last edited on May 31, 2012 at 12:14am May 31, 2012 at 12:14am UTC