C++ class object inside another class problem - c++

I working on a project and I have a lot of classes that have instances of other classes as fields. The problem is that I must declare the classes in a specific order in order for the code to compile. Example below:
class A{
public:
B* b; //unknown type name B
A(){
b = new B();
}
};
class B{
public:
B(){
}
};
The code above does not work, because it says that B is unknown.
But, if I declare class B before A
it's working fine.
class B{
public:
B(){
}
};
class A{
public:
B* b; //Works perfectly
A(){
b = new B();
}
};
In my project, there's no way to re-arrange the classes in order for the error to go away.
Is there a way to bypass this error?

In my project, there's no way to re-arrange the classes in order for the error to go away. Is there a way to bypass this error?
You are describing a circular dependency. X depends on Y and Y depends on X. Such dependency is unsolvable. If you can remove a dependency on one class from another class, then it may be possible to re-order the definitions so that all dependencies are satisfied. Sometimes dependency can be removed by introducing indirection.
Note that just because one class definition (A) depends on declaration of another class (B), that doesn't necessarily mean that it depends on the definition of that class. You can have one class depend on the definition of another class, while still having the dependee class depend on the declaration of the depender.
Furthermore, just because definition of a member function (A::A) depends on definition of another class (B), that doesn't necessarily mean that the class (A) has that same dependency. This is because it is not necessary to define member functions within the class definition.
For example, your example class A does not depend on the definition of B. As such, A can be defined before B:
// declaration of B
// not a definition
class B;
// definition of A
class A{
public:
B* b; // depends on declaration of B
// does not depend on the definition
A();
};
// definition of B
class B{
public:
B(){
}
};
// definition of A::A
// does depend on definition of B
A::A() {
b = new B();
}

Related

Wrong use of forward declaration?

Sometimes I use foreward declaration for nested classes:
class A;
class B
{
private:
A* object_A;
public:
B(){}
};
The question: What happens if I now use forward declaration of class B (B is declared and defined at this point) for the useage in class C? Does this cause any problems with class B, because it is defined (with implementation of methods etc.) but is used with forward declaration for class C? Does the syntax class B; in the following code-snippet overwrites somehow the previous declared, defined and implemented class B?
class B;
class C
{
private:
B* object_B;
public:
C(){}
};
Does the syntax class B; in the following code-snippet overwrites somehow the previous declared, defined and implemented class B?
Forward declarations are not about overwriting. It is just giving hint to the compiler that the type definition is implemented somewhere. For user defined pointer types, compiler does not require the definition but needs to know what is the type of the object.

Alternative for forward declaration: two classes using each other

I have class A which has to implement some functions. Since implementing one of them needs it's own data structures, I assumed A contain another class B, which has all needed data structures and functions. However, B is also need to use data structures and functions of A, as well. I used two classes calling each others using forward declaration. But there is still problems. For example, I need to make all data structures in A public, in order to B can access it. I tried using friend classes, but when I declare B as an abstract classes with sub-classes which implements B's functionalities, I need to make all data structures of A, as public. Because friend class doesn't work for inherited sub-classes, all data structures of A, needs to be public. This makes my design quite messy.
class B;
class A{
protected:
int ds[100];
B * b;
public:
a_func(){
b->b_func();
}
};
class A;
class B{
A * a;
public:
b_func(){
a->a_func();
}
};
class sub_B:public B{
public:
b_func(){
a->a_func();
a->ds ...;
}
}
My question is: is there any alternative design?
I also tried making A an abstract class and class B implements a function of it, however, it doesn't conceptually makes sense to build an object of B, when I want an object of A.
You don't have to provide member function definitions inside a class definition:
class A;
class B;
class A {
// no need for public
B * b;
void a_funct(void);
};
class B {
// no need for public here, too
A * a;
void b_funct(void);
};
// the following goes in a source file,
// otherwise you should mark it as inline
void A::a_funct() {
b->b_funct();
}
void B::b_funct() {
a->a_funct();
}
Note that above code serves only as example, in its current shape it's nothing but a fancy endless (recursion) loop.

Class prototyping

I have put several instances of class b in class a but this causes an error as class a does not know what class b is.
Now I know I can solve this problem by writing my file b a c but this messes up the reachability as well as annoys me. I know I can prototype my functions so I do not have this problem but have been able to find no material on how to prototype a class.
does anyone have an example of class prototyping in c++.
as there seems to be some confusion let me show you what i want
class A
{
public:
B foo[5];
};
class B
{
public:
int foo;
char bar;
}
but this does not work as A cannot see B so i need to put something before them both, if it was a function i would put A(); then implement it later. how can i do this with a class.
You can declare all your classes and then define them in any order, like so:
// Declare my classes
class A;
class B;
class C;
// Define my classes (any order will do)
class A { ... };
class B { ... };
class C { ... };
You're looking for declarations.
class A;
class B {
A MakeA();
void ProcessA(A a);
};
class A {
B bs[1000];
};
If you forward declare a class, you can
declare functions taking and returning it or complex types made of it
declare member variables of pointer or reference to it
This basically means that in any case which doesn't end up with instances of A inside B and vice versa, you should be able to declare and define any interface between A and B.
The usual way to resolve circular dependencies is to use a forward declaration:
// Bar.h
class Foo; // declares the class Foo without defining it
class Bar {
Foo & foo; // can only be used for reference or pointer
};
// Foo.h
#include <Bar.h>
class Foo {
Bar bar; // has full declaration, can create instance
}
You can provide a full declaration and definition in another file. Using the forward declaration, you can create pointers and references to the class, but you cannot create instances of it, as this requires the full declaration.
class b;
class a {
public:
b * inst1;
};
class b{
....
};
Is this what you needed ?

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.

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.