Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

forward declaration generates incompatible type error

Tags:

c++

I've been reading some on forward declarations, including in this forum. They all say that it saves us from including the header file, However the following code generates an error:

#ifndef CLASSA_H_
#define CLASSA_H_

class B;

class A {

public:
    A();
    ~A();
    int getCount();
private:
    static int _count;
    int _num;
    B _b1;   //ERROR

};

compiler says: A.h:23: error: field ‘_b1’ has incomplete type

I noticed that if i make _b1 of type B* the problem is solved.

So is forward declaration good only for pointer types?
If i want A to hold B object i have to #inlcude "B.h" ?

thanks!

like image 735
Asher Saban Avatar asked Sep 29 '10 15:09

Asher Saban


People also ask

What does forward declaration do?

Forward Declaration refers to the beforehand declaration of the syntax or signature of an identifier, variable, function, class, etc. prior to its usage (done later in the program). In C++, Forward declarations are usually used for Classes.

What is the advantage of forward declaration?

Forward declarations in C++ are useful to save in compile time as the compiler does not need to check for translation units in the included header. Also it has other benefits such as preventing namespace pollution, allowing to use PImpl idiom and it may even reduce the binary size in some cases.

Can you forward declare a namespace?

There is no forward declaration of namespace.


2 Answers

The compiler has to know the exact definition of class B to determine at least what size to give to class A. If you use a pointer, it knows its size.

Note that circular dependencies are not possible. If you want

class A { B b; };
class B { A a; };

then A and B must have infinite size...

like image 86
Alexandre C. Avatar answered Nov 15 '22 06:11

Alexandre C.


You can use a forward-declared type to

  1. use pointers and references to it as data members
  2. use it as an argument (even taking per copy) or return type (even returning per copy) for function declarations.

You will need a full definition of a type in order to

  1. use it as class data member
  2. use it in function definitions.

If you remember that a forward-declaration actually is a misnomed declaration (there is no other way of declaring a class type, so any declaration of a class type is a forward declaration), and that, whenever you are opening the braces after class/struct/union plus identifier, you are defining a class, all you need to remember is that you:

  • need a full definition to use the type itself in definitions
  • get away with only a declaration to use the type itself in declarations
  • get away with only a declaration when you use only pointers and references and do not try to access members or nested types (anything with ., ->, and :: in front)
like image 20
sbi Avatar answered Nov 15 '22 07:11

sbi