So lets say I have a class called Foo and another called Bar. Bar contains an instance of Foo and I have a function in Foo that takes Bar as a parameter. However, when I #include "Bar.h" in Foo to allow Foo to see Bar I get this error on the lines that Bar is referenced on:
error: ISO C++ forbids declaration of 'Foo' with no type
I'm guessing this is because both of the classes rely on each other to compile. Is there any way to get around this?
EDIT: Both of these classes have header files where the other class is referenced inside a #ifndef declaration.
In Foo.h instead of including Bar.h you need to use the forward declaration class Bar;. Note that for this to work you need to take the parameter Bar as a reference or a pointer in Foo class.
class Foo;
class Bar
{
};
and
class Bar;
class Foo
{
};
But this might be a result of a wrong design!!
You'll need to use a forward declaration for at least one class:
Foo.h:
#include "Bar.h"
class Foo {
};
Bar.h:
class Bar;
#include "Foo.h"
class Bar {
};
Also beware that you cannot easily reference members of Bar in Foo.h (they're not declared). So any inlined members that need Bar will have to go in Foo.cpp (or .cc if you prefer). You also cannot have a Bar as a value member of Foo.
So:
class Bar {
Foo f; // OK. Compiler knows layout of Foo.
};
class Foo {
Bar b; // Nope. Compiler error, details of Bar's memory layout not known.
Bar *b; // Still OK.
};
This is especially tricky for templates. See the FAQ if you have troubles.
Use references or pointers for parameters and forward declarations. E.g.
//foo.h
class Bar;// the forward declaration
class Foo {
void myMethod(Bar*);
};
//foo.cpp
#include "bar.h"
void Foo::myMethod(Bar* bar){/* ... */}
//bar.h
#include "foo.h"
class Bar {
/*...*/
Foo foo;
};
Related
Suppose we have two classes Foo and Bar.
We can declare the Foo class and use its methods as following:
#include"foo.h"
Foo foo
class Bar{
Bar(){
foo.method1();
}
}
And we have the forward declaration, which stands to declare the Foo class as following:
#include"foo.h"
class Foo
class Bar{
Bar(){
}
}
What are the main differences between the two declartions, and when the forward declaration is prefered to the normal declaration?
In second case you don't need
#include"foo.h"
In forward declaration you just say compiler "There are Foo class somewhere. But I don't know how it look". So compiler can refer them but can't use them;
class Foo; //Forward declaration.
Foo* foo; // ok. Just pointer.
Foo foo;// error. Compiler can't instantiate object.
and
#include "foo.h"
Foo* foo; // ok. Just pointer.
Foo foo;// ok. Compiler can instantiate object.
So, in some case forward declaration can replace the inclusion of a header file.
I've been looking at examples for a component-based system and in some of the examples, I noticed the usage of class names outside of other classes like in the example below. What is the purpose/function of creating class Foo; and class Bar; and what is this called?
#pragma once
#include "foo.h"
#include "bar.h"
class Foo; // ???
class Bar; // ???
class Example
{
public:
Example() :
m_pExample(0) {}
virtual ~Example() {}
void something(const Foo& foo, const Bar& bar);
private:
Example* m_pExample;
};
It is called a forward declaration and declares class name as a valid but leaves out the definition. This mean that you can use the name as a type before the definition is encountered.
What are forward declarations in C++?
Those are called forward declaration
This help the compiler know that the type exists and it knows nothing about its size, members, and methods.
Therefore its a an incomplete type too.
Actually if you already have #include "foo.h" and #include "bar.h" (assuming the class definition of each class is already in its related .h file), I don't see why you should have the two class Foo; and class Bar; statement.
Usually the reason of putting the class Foo; and class Bar; is that you are going to provide the definition of the two classes yourself.
Example:
#pragma once
class Foo;
class Bar;
class Example
{
public:
Example() :
m_pExample(0) {}
virtual ~Example() {}
void something(const Foo& foo, const Bar& bar);
private:
Example* m_pExample;
};
class Foo
{
// Definition of Foo class goes here...
;
};
class Bar
{
// Definition of Bar class goes here...
;
};
Foo.h
class Foo{
private:
void printSpecialBar(Bar b);//syntax error: Identifier Bar
Foo.cpp
#include "Bar.h"
void Foo::printSpecialBar(Bar b)
{
//code goes here
}
Bar has the default constructor and one that takes two int's.
What is the problem with the syntax error? I tried using the scope resuloution operator Bar::Bar b but it didn't fix it.
A typical practice would be to put
class Bar;
in Foo.h, before any reference to Bar class, and include the actual class like
#include "Bar.h"
in Foo.cpp.
Since Foo.h references Bar, either use a forward declaration or #include "Bar.h" in Foo.h
I am having trouble working out some kinks in a design implementation. It goes something like this:
I have a template base class which has a conversion method.
// Foo.h
class Bar;
template<typename T>
class Foo {
virtual const Bar toBar();
}
I want a derived class Bar to inherit from a specific form of Foo for example:
// Bar.h
class Bar : public Foo<float> {
// Insert Bar methods here, Etc.
}
As Foo is a template the implementation has to be fully defined in the header, this causes the problem that the implementation of the method toBar() will need to be able to create an instance of type Bar. So that tells me I need to include the Bar.h header file after the Foo definition but before the Foo implementation.
However, in Bar.h the class Bar is derived from Foo so a full definition of Foo must be provided. This causes problems because the two files have a cyclic dependency that cannot be solved via forward declarations because the forward declaration is a derived class.
This get even more complicated if another class SomeClass has a data member of type Bar as this required including the Bar.h which includes the Foo.h which (because it is a template)
includes Bar.h.
Oh and just to be clear all the header files have inclusion guards using
#ifndef _HEADER_NAME_H_
#define _HEADER_NAME_H_
...
#endif
How have other people solved complex issues like this?
As a more concrete example say I have an Array class that has a method to convert it to a human readable String class such as toString()...however the String class is declared as being as
class String : public Array<char> {...};
Thanks in advance.
Gary.
In order for Foo< float > to be a base class, it must have been fully defined by the point of Bar definition. However, Foo doesn't necesarily need to know about Bar, if you could make Bar be a dependent typename within Foo.
A forward declaration of Bar before defining Foo may be enough. If you post/link more concrete code, I may be able to give you a better answer.
Try this:
class Bar;
template< typename T, typename DependantBar = Bar >
class Foo {
virtual const DependantBar toBar();
}
class Bar : public Foo<float> {
template <typename T>
Bar create(const Foo<T>&);
}
I want to hide an implementation in implementation file. If the object is not public, I don't want the object's header to leak everywhere my class is used.
Suppose I have header file A.h for my class A:
#include "Foo.h"
class A{
private:
Foo foo;
public:
do_stuff();
};
Now wherever I would include A.h, Foo.h also would be included. But I have no use for class Foo anywhere outside of class A. I would rather not have this #include "Foo.h" line. Is there any way to move the declaration of 'foo' variable inside the implementation A.cpp?
I suspect one possible solution involves adding a layer of abstract class (interface analogy). Is it the best solution?
Thank you.
Use a pointer to Foo and allocate it dynamically, rather than using a member object. Then you only need to include Foo.h in A.cpp.
class Foo;
class A{
private:
Foo* foo;
public:
do_stuff();
}
David's got the right answer. I'll refer to this article for a little more treatment on this kind of "opaque pointer" trick, as you can get more elaborate with it, depending on your needs:
http://en.wikipedia.org/wiki/Opaque_pointer
Also, it's a good idea to use shared_ptr types for this purpose instead of raw pointers like the sample. This will take care of cleaning up resources for you automatically, once the last reference to Foo goes out of scope.
Yes. Choose yer poison!
Option 1. Forward declaration in interface.
class A {
private:
class Foo;
Foo* foo;
};
Option 2. ABC.
// A.hpp
class A {
public: virtual void do_stuff() = 0;
};
// A.cpp
class A_impl : public A {
class Foo { /*etc*/ };
Foo foo;
void do_stuff (){...}
};
Option 3. Private is private. It's "hidden" as far as the public API goes, which is all that matters:
class A {
private:
class Foo {
...
};
private_::Foo foo;
public:
do_stuff();
};
Option 4. Just put the declaration in a "non-public" namespace.i.e., omit it from documentation and name it something to frighten away prying eyes:
namespace private_ {
class Foo {
...
};
}
class A {
private:
private_::Foo foo;
public:
do_stuff();
};