-2

I have the following code:

Foo.h:

include "Bar.h"

class Bar;

class Foo {
   const Bar mBar;

public:
   Foo(const Bar &bar);
};

Foo.cpp:

#include "Foo.h"

Foo::Foo(const Bar &bar) : mBar(bar) {}

I receive the following compilation error:

'Foo::mBar' uses undefined class 'Bar'

Is const definition not allowed in implementation file?

Obviously in this case I could move ctor implementation into header file.

But What is an alternative if I want to call Bar ctor which may take arguments requiring forward declaration instead of copy ctor and still keep Bar member variable constant? So for example:

Foo.h:

include "Bar.h"

class Bar;
class BaraParams;

class Foo {
   const Bar mBar;

public:
   Foo(const BarParams &barParams);
};

Foo.cpp:

#include "Foo.h"

Foo::Foo(const BarParams &barParams) : mBar(barParams) {} //call bar ctor

Bar.h:

include "BarParams.h"

class Bar{
public:
   Bar(const BarParams &barParams);
};

Or am I not doing this right? I don't even know if this is a good idea.

Chebz
  • 1,375
  • 3
  • 14
  • 27
  • 1
    The compilation error has nothing to do with the `const` qualifier. As `mBar` is neither a reference, nor a pointer to a `Bar`, the compiler needs to know the size of a `Bar`, which requires `Bar` to be defined once the compiler encounters the `mBar` member variable. – foobar Aug 08 '15 at 19:21
  • hmm so I can use a reference or pointer only? – Chebz Aug 08 '15 at 19:23
  • No, you can also use a plain `Bar` if you just define `Bar` before `Foo`. The definition of class members is usually done in header files, so that the `#include` preprocessor directive for the corresponding header file of the `Bar` class is sufficient if you organized your source code correctly. – foobar Aug 08 '15 at 19:26
  • ahh so it could be order of declarations? in my real code, which is too big to paste here I use stdafx.h to keep all includes. And include stdafx.h instead.. perhaps that's the problem? – Chebz Aug 08 '15 at 19:27
  • If you `#include "stdafx.h"` in `Foo.h`, then you have to `#include "Bar.h"` before `#include "Foo.h"` in the `stdafx.h` file and add include guards to your header files if you didn't do that already. So yes, it's most likely a problem in the order of declaration. – foobar Aug 08 '15 at 19:35
  • If you use references or pointers don't include the header files where these classes are defined but use forward declarations. As explained in my answer. – Philip Stuyck Aug 08 '15 at 19:36

1 Answers1

0

The header file has to include the Bar header file. The full thing is like this :

include "Bar.h"

class Foo {
   const Bar mBar; 
   //because it is Bar and not Bar& or Bar* forward declarations are not possible

public:
   Foo(const Bar &bar);
};

You can and should use forward declarations in following situation

class Foo {
   const Bar& mBar; 

public:
   Foo(const Bar &bar);
};

but then the Bar include has to be present in the implementation file.
The same reasoning can be applied here instead of this :

include "BarParams.h"

class Bar{
public:
   Bar(const BarParams &barParams);
};

do this :

class BarParams;

class Bar{
public:
   Bar(const BarParams &barParams);
};

Doing that avoids unneeded includes all over your header files, and makes the life of your compiler a lot easier. In large projects the compilation times can be reduced significantly.

Philip Stuyck
  • 7,344
  • 3
  • 28
  • 39
  • well in my real code, which is too big to paste here I use stdafx.h to keep all includes. And include stdafx.h instead.. perhaps that's the problem? – Chebz Aug 08 '15 at 19:25
  • I am getting a bunch of incomplete type errors now if I want to do anything with BarParams besides reference them. – Chebz Aug 08 '15 at 20:30
  • the include is needed in the implementation file. Also take a look at this http://stackoverflow.com/questions/9906402/should-one-use-forward-declarations-instead-of-includes-wherever-possible – Philip Stuyck Aug 08 '15 at 20:49