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 ?
Related
For example, class A has a member of class B. In general, for the purpose of minimizing compilation dependency, we often make class A include B's pointer, and pre-declare class B in the class A's declaration. Looks like this:
//B.h
class B
{
....
};
//A.h
class B;
class A
{
B*b;
A();
...
};
//A.cpp
#include "B.h"
A::A()
{
b=new B();
...
};
But now I have a question: if the class of B is defined using typedef like this:
typedef class
{
....
}B;
The previous pre-declared method will not work in this case. How should I pre-declare the class B in A.h?
In the code typedef class { .... } B; , it is an unnamed class, with B being a type alias for the unnamed class.
It is not possible to declare an unnamed class without defining it (i.e. providing the class body); and it is not possible to declare that B is a typedef for an unnamed class.
There is no such thing as a forward declaration of a typedef. In general a typedef can declare an alias for incomplete type that is completed later, but an unnamed class cannot fill either of those roles.
Removed further advice in response to voter feedback
Note: the question used the term "pre-declare". The C++ Standard does not use the terms "pre-declare" or the more common jargon "forward-declare". In the standard's terminology, a forward declaration of a class is simply called a class declaration. This can be clarified by saying "declaration that is not a definition" if it is not clear from context already.
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.
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;
};
If I define a nested class and then create an instance like this:
class A
{
class B
{
...
};
B b;
};
everything is ok. But if I just declare B inside of A and define it outside, I can't create an instance of B, probably because the compiler don't know how much space the instance of B will need. But code is not much readable when you define a class inside another. Is there a way to make this work?
class A
{
class B;
B b;
};
class A::B
{
...
};
Simple, just define class B, then define an instance of it in A.
class B
{
}
class A
{
B memberB;
}
Or you can forward declare it:
class B;
class A
{
B memberB;
}
class B
{
}
Truly nested classes are rarely needed and not very useful at all.
When you use a class type as a member, the concrete class needs to be known. That's why your second case doesn't work. A work around is to use pointer to B:
#include <memory>
class A
{
class B;
std::unique_ptr<B> b;
};
class A::B
{
};
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.