forward declare derived class from template c++ - c++

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>&);
}

Related

Can I omit non-public inheritance for forward-declaration of classes?

Let's say I have a piece of code like this:
// Foo.h:
class Incomplete; // the forward-declaration
class Foo {
void bar(Incomplete&); // doesn't really matter
};
// Foo.cpp:
class Incomplete : private Baz {
};
void Foo::bar(Incomplete&) {
}
Is forward-declaring classes like in Foo.h standard-compliant? If it is, since which language version? What about the same for protected inheritance?
A forward declaration of a class is required to omit inheritance. You cannot write
class Incomplete : private Baz;
even if you wanted to.
The purpose of a forward declaration is to simply indicate that a particular name in a particular namespace refers to a class. Specifying the base class is part of the definition since it gives information about the class's layout in memory.

Avoiding Circular Dependencies in Class Definitions in C++

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.

Error with two classes that #include each other

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;
};

Class prototyping

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 ?

Is it possible not to include a class variable in a class header file?

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();
};