identifier "xxx" is undefined, class pointer and struct - c++

I am writing a small c++ - program containing a similar structure to the following:
class A {
B * someObjects;
};
typedef A* APointer;
struct B{
APointer a;
int n;
}
Trying to compile this gives a "identifier is undefined" error since struct B is not known inside class A. Otherwise declaring struct B before class A should still give a similar error, since then B does not know APointer, or APointer does not know A. Is there any possibility to make class A and struct B being good friends?
Thanks in advance!

You need to forward declare B as the compiler has no idea what B is when it is used in A. B is considered an incomplete type in A and you are allowed to have a pointer or reference to B in A. You can change your code to:
struct B;
class A {
B * someObjects;
};
typedef A* APointer;
struct B{
APointer a;
int n;
};

Have you ever heard the term Forward Declaration! Your compiler don't know about B yet. So give a declaration of B first.
struct B; // forward declaration
class A {
B * someObjects;
};
//... rest of the code

Related

Regarding forward declaration c++ class

I have two classes like this:
class B;
class A {
public:
int a, b;
B *b;
public:
int getctxt()
{
b->getctxt1();
}
}
Class B {
public:
int c,d;
A *a;
getctxt1()
{
/* something */
}
}
main()
{
B *b = new B();
A *a = new A();
b->a = a;
a->b = b;
}
But when I try to compile, it says
invalid use of incomplete type ‘struct A’.
Can anyone tell me how to solve this?
Inline class member function definitions are parsed as if they appeared right after the class definition. Of course B isn't defined at that point. So move the member function definition for A::getctxt out of the definition of class A:
class B;
class A { int getctxt(); /* ... */ };
class B { /* ... */ };
int A::getctxt()
{
b->getctxt1(); // at this point, *b has complete type!
return -35;
}
This is the reason why it is recommended to separate your classes in a .h file and a .cpp file. When you write class B;, you are telling the compiler that there is a class called B, but that's it, the compiler does not know what is inside this class. When the compiler reaches the line b->getctxt1();, it knows that b is an instance of B, but it does not know if getctxt1() is a method of B, because that is below. If you are writing all in a single file, you should first write all the declarations, and then all the implementations.
didn't anyone notice Class B syntax error? lowercase class is correct.
and those two public members in A with the same name int b and B *b.
once you remove those and finish class definitions with semicolons, add a void type to the void getctxt1() that is missing it in B.
just define functions as they should be defined. not inline without a reason that you know which is!

How can I define two inter dependant classes, preferably in the same header file?

So, I want something like:
class A{
B member;
};
class B{
A function();
};
No matter in which order I declare them, I get an incomplete type error (and I pretty much understand why).
How can I solve this? I don't want to use pointers or to have the function defined outside the B class. Also, declaring them before as
class A; class B;
doesn't seem to work either.
No need for class definition when declare a function.
class A;
class B{
A function();
};
class A{
B member;
};
This order will work:
class A;
class B {
A function();
};
class A {
B member;
};

How to use class which defined below?

class A{
public:
B b;
};
class B{
public:
A a;
};
I can't write in A class "B b" because class B defined below. Is any way to make it work?
thanks
This is not possible. You need to use a pointer or a reference in one of the classes.
class B; // forward declare class B
class A {
public:
B * b;
};
class B {
public:
A a;
};
As to why it isn't possible: A contains a B contains an A contains a B ... There's no end to the recursion.
If you're used to languages (such as e.g. java) where all object variables are pointers/references by default, note that this is not the case in c++. When you write class A { public: B b; }; a complete B is embedded into A, it is not referred to within A. In C++ you need to explicitly indicate that you want a reference (B & b;) or a pointer (B * b;)
Think about it: Inside an object of class B there's an object of class A, and inside it there's an object of class B. This is physically impossible! What will be the size of object B?
sizeof(B) > sizeof(A) > sizeof(B)
You must use pointers, like the other answer suggested.
There is no way to make it work. You should use forward declaration and a pointer to one of the class
class B;
class A{
public:
B *b;
};
class B{
public:
A a;
};
That is because when you're writing B b the compiler must know what B is. But if you make a forward declaration then compiler will know that B is some class and you will be able to create pointers and references of B.
Only if you change at least one of the two member objects to a pointer. You would be able to declare a member pointer to such an object by forward-declaring the other class, like this:
class B;
class A{
public:
B* pb;
};
class B{
public:
A a;
};
The reason for this:
The compiler needs to know how objects of each class (A and B) will be laid out in memory. This includes how much memory will be needed for each object. Since class members require an amount of memory that depends on their members, it follows that the compiler can only allow you to declare a class member if it has seen the declaration of that member's class first.
Pointers, on the other hand, always take up the same amount of memory. This is why it's enough for you to tell the compiler "B is a class; I want a pointer to B here". The "B is a class" part corresponds to the class B; line above, which is called a forward declaration.

C++ recursive data types

A bit of a noob question:
I need classes A and B such that A has a B* member and B has an A* member.
When compiling I get "error: ISO C++ forbids declaration of ‘B’ with no type". How can I get around this?
Forward declare B (or A )
class B; //forward declaration of B
class A
{
B *b;
};
class B
{
A *a;
};
Forward declare one of class a or b.
class b; //forward declaration
class a{
//class a stuff
b* ptrtoB;
};
class b{
//class b stuff
a* ptrtoA;
};
You can also inline forward declare one of the classes if nothing else is using it: class B* pMemberB; al la C style

Declare an object even before that class is created

Is there anyway to declare an object of a class before the class is created in C++? I ask because I am trying to use two classes, the first needs to have an instance of the second class within it, but the second class also contains an instance of the first class. I realize that you may think I might get into an infinite loop, but I actually need to create and instance of the second class before the first class.
You can't do something like this:
class A {
B b;
};
class B {
A a;
};
The most obvious problem is the compiler doesn't know how to large it needs to make class A, because the size of B depends on the size of A!
You can, however, do this:
class B; // this is a "forward declaration"
class A {
B *b;
};
class B {
A a;
};
Declaring class B as a forward declaration allows you to use pointers (and references) to that class without yet having the whole class definition.
You can't declare an instance of an undefined class but you can declare a pointer to one:
class A; // Declare that we have a class A without defining it yet.
class B
{
public:
A *itemA;
};
class A
{
public:
B *itemB;
};
There's an elegant solution using templates.
template< int T > class BaseTemplate {};
typedef BaseTemplate< 0 > A;
typedef BaseTemplate< 1 > B;
// A
template<> class BaseTemplate< 0 >
{
public:
BaseTemplate() {} // A constructor
B getB();
}
// B
template<> class BaseTemplate< 1 >
{
public:
BaseTemplate() {} // B constructor
A getA();
}
inline B A::getB() { return A(); }
inline A B::getA() { return B(); }
This code will work! So, why does it
work? The reason has to do with how
templates are compiled. Templates
delay the creation of function
signatures until you actually use the
template somewhere. This means that
neither getA() nor getB() will have
their signatures analyzed until after
both classes A and B have already been
fully declared. That's the magic of
this method.
Is this close to what you want: The first class contains the second class, but the second class (that is to be created first) just has a reference to the first class?
This is called cross reference. See here an example.