I currently have two classes: foo and bar. Foo uses instances of bar in one of its methods, and bar uses an instance of foo in its constructor. However, this will not compile. I understand that there is a circular dependence, so I tried to break out of this by forward declaring bar inside of foo before the foo's method is declared in the header file. That failed because I cannot actually use bar or any of its components at all in foo's method in the source file. I then tried rearranging it so that everything in the source file that bar needed was already defined, then I put in all the definitions for bar, then I defined the method in foo that uses bar. That failed for the same reason. Here is a simplified version of my code so far:
// Header.h
class foo{
class bar;
void method(bar& b);
};
class bar{
bar(foo& f, double d);
};
// Source.cpp
#include Header.h
// stuff defining foo that I need for bar in the form foo::foo(...){...}
// stuff defining bar that I need for foo::method
void foo::method(bar& b){
// do stuff with foo and b
}
I would like to point out that when I remove references to the instance of bar in the definition of foo::method, the code compiles and runs properly.
My specific example has the foo class as a vector in homogenous coordinates and the bar class as a quaternion. The quaternion class uses a vector and an angle of rotation in its constructor, and the vector class uses the quaternion in its rotation method.
Is there a way to code this without removing the dependencies or should I just remove one of the dependencies?
Try forward declaring bar outside of foo:
class bar;
class foo{
method(bar& b);
}
class bar{
bar(foo& f, double d);
}
As you had it there you were forward-declaring a class called foo::bar.
Related
I'm getting this strange problem which I don't know why happens. The first and second of the following code snippets compile, while the third does not:
Compiles:
class Foo {
public:
Foo() { Bar(); }
private:
class Bar {};
};
Compiles:
class Foo {
class Bar {}; // Or only forward declare here and define later
public:
Foo(Bar) {}
}
Does not compile:
class Foo {
public:
Foo(Bar) {}
private:
class Bar {};
};
What makes the third fail to compile while the first can?
Normally, in C++, you can only reference declarations that were previously made in the translation unit. However, within a class definition, the definition of member functions are allowed to reference declarations which are made later in the class. Basically, the compiler restructures your in-class definitions so that they work as though they were written just after the class.
But this is only true of the function definitions. The declaration of the function (including parameter types) isn't allowed to do this. They can only reference declarations that have already been made in file order.
So you can do this:
class Test
{
public:
void Func(int x) {Inner foo;}
private:
class Inner {};
};
But not this:
class Test
{
public:
void Func(Inner x) {}
private:
class Inner {};
};
First example does not expose anything about private Bar to the outside, while third does.
Third example is pretty much saying, that there exist some class Foo, which has constructor with single argument of type Bar. But Bar is unknown to the outside. Imagine calling such constructor.
Foo f{Foo::Bar{}};
Will result probably in something like Foo::Bar is inaccessible.
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;
};
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 have put several instances of class b in class a but this causes an error as class a does not know what class b is.
Now I know I can solve this problem by writing my file b a c but this messes up the reachability as well as annoys me. I know I can prototype my functions so I do not have this problem but have been able to find no material on how to prototype a class.
does anyone have an example of class prototyping in c++.
as there seems to be some confusion let me show you what i want
class A
{
public:
B foo[5];
};
class B
{
public:
int foo;
char bar;
}
but this does not work as A cannot see B so i need to put something before them both, if it was a function i would put A(); then implement it later. how can i do this with a class.
You can declare all your classes and then define them in any order, like so:
// Declare my classes
class A;
class B;
class C;
// Define my classes (any order will do)
class A { ... };
class B { ... };
class C { ... };
You're looking for declarations.
class A;
class B {
A MakeA();
void ProcessA(A a);
};
class A {
B bs[1000];
};
If you forward declare a class, you can
declare functions taking and returning it or complex types made of it
declare member variables of pointer or reference to it
This basically means that in any case which doesn't end up with instances of A inside B and vice versa, you should be able to declare and define any interface between A and B.
The usual way to resolve circular dependencies is to use a forward declaration:
// Bar.h
class Foo; // declares the class Foo without defining it
class Bar {
Foo & foo; // can only be used for reference or pointer
};
// Foo.h
#include <Bar.h>
class Foo {
Bar bar; // has full declaration, can create instance
}
You can provide a full declaration and definition in another file. Using the forward declaration, you can create pointers and references to the class, but you cannot create instances of it, as this requires the full declaration.
class b;
class a {
public:
b * inst1;
};
class b{
....
};
Is this what you needed ?
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();
};