Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problem with declaring Objects in C++

Tags:

c++

oop

I have a simple code below:

class B;
class A{
    B b;
};

class B{
public:
    B(){

    }
};

In class A's definition, I have a B-typed property. Using MS Visual Studio to compile, I've got the following error:

error C2079: 'A::b' uses undefined class 'B'

Due to some reasons, I can't put class B's definition before class A's one. Any idea?

like image 580
anhldbk Avatar asked Apr 17 '26 05:04

anhldbk


2 Answers

The compiler is already telling you what's wrong : A has a member data b which is of an undefined type. Your forward declaration:

class B;

is just that : a declaration, not a definition. Since class A contains an instance of B directly (not just a pointer to B), the compiler needs to know the exact size of B : it needs its definition, not just a declaration, i.e. a promise that B will exist at some point.

The simplest thing to do here would be to reorder things this way:

class B{
public:
    B(){

    }
};

class A{
    B b;
};

Edit : see also this question for the difference between declaration and definition.

Further edit : an alternative would be to change your member data to a pointer or a reference. Do note that this isn't a trivial syntax change: it has implications on the life-cycle of your objects since the object pointed by A::b may then survive the destruction of A.

If what you want is composition (B is a part of A and dies with A), using a pointer will make your life harder with little benefits.

More edits(!) : just realized I misread the end of your question; what are the reasons preventing you from declaring B before A ?

If they cannot be worked around, you may have to go the pointer route. These reasons might be a sign that your objects are too tightly coupled though ! (perhaps B needs to be an inner class of A ? Or simply be merged into a single object ?)

like image 127
Nicolas Lefebvre Avatar answered Apr 18 '26 20:04

Nicolas Lefebvre


class A;

class B {
  A * getA();
};

class A {
  B b;
};

This is the typical way to solve this. You must have B's definition in order to have a B b; member.

You need a forward declaration in order to declare a reference/pointer to B, you need the full definition in order to do anything else with B (such as defining a variable, calling a member function and so on)

like image 44
Erik Avatar answered Apr 18 '26 21:04

Erik