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.
Related
Hi I know the title is a little hard to understand, and that's just because I have no idea how to phrase this problem. Fortunately, I can provide an easy-to-understand example of my problem. Imagine a base class A derived class B and unrelated class C setup as follows:
class A
{
public:
};
class B : public A
{
public:
C c;
};
class C
{
public:
void foo();
};
I want to know how to call foo() using an object of class B without doing this:
B b;
b.c.foo();
but rather this:
B b;
b.foo();
Additionally, I don't want to inherit from class C or make copies of class C's functions. Is this possible with a simple implementation? Thanks!
Your constraints mean your example does not make sense unless the function foo is static; if it is not then you need to provide information about the instance of C you are using before foo makes sense; so mentioning c would be essential. If it is static then C::foo works but not b.foo(). If you want a member function for B that calls b.c.foo() then you should write one as suggested above.
Perhaps you meant to privately inherit C in B:
class B : private C , public A
{
public:
using C::foo;
};
will do the trick.
Suppose I have outer class as A and a inner class B
template <class T, class K>
class A::public T::RadioSignal, public VarMethod<T> {
private:
B *bObject;
public:
class B : public std::vector<SamplePoint*>
{
public:
B(A<K, T> *outerInstance);
};
}
I am getting below error: Unknown type name 'B'
That error is at line B *bObject; ? But at that moment the class B is not yet defined.
Either define the inner class ahead of it, or use forward reference. (class B; is probably enough?)
edit: if you would use not only pointer, but also something more of B (like B bObject; -> class B; would be not sufficient, but as you are using only B *, it should be enough just to forward declare existence of the class B. Then again, I would try to stay away from bare pointer usage, why don't you declare the full class B first and then declare directly B bObject; as member instance of A? So you don't have to deal with new/delete.
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.
Here is some code that fails in VS2012:
class A;
class B
{
bool A();
A member; // Error: function B::A is not a type name
};
Why doesn't this work? Obviously I'm trying to create a member of type A, not of type B:A() (which isn't a type, as the compiler correctly points out). Is there some way around this without changing the names of either B:A() or class A? Can I explicitly tell the compiler that I want member to be of type class A?
It's possible, you just need to make clear that you want to use the class A:
class A;
class B
{
bool A();
class A member;
};
It fails because they share a namespace. C++ cannot, in general distinguish types and functions based on context (is A() a constructor or a function call). You can make it explicit which one you refer to, e.g.
class A;
class B
{
bool A();
::A member;
};
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.