Reputation: 482
I have a class design problem that could simplified with this example:
// foo.h
#include "foo2.h"
class foo
{
public:
foo2 *child;
// foo2 needs to be able to access the instance
// of foo it belongs to from anywhere inside the class
// possibly through a pointer
};
// foo2.h
// cannot include foo.h, that would cause an include loop
class foo2
{
public:
foo *parent;
// How can I have a foo pointer if foo hasn't been pre-processed yet?
// I know I could use a generic LPVOID pointer and typecast later
// but isn't there a better way?
};
Is there any other way other than using a generic pointer or passing the parent pointer to every call of foo2 members?
Upvotes: 1
Views: 4860
Reputation: 1468
Forward declaration is a friend:
// foo.h
class foo2;
class foo
{
foo2 *pFoo2;
};
// foo2.h
#include "foo.h"
class foo2
{
foo *pFoo;
};
As Pubby says, though, classes that need to know about each other should probably just be one class, or maybe a class, with two members, both of which know about the parent class, but not as a two-way relationship.
As far as parenthood and being generic goes:
template <class Parent>
class ChildOf
{
public:
// types
typedef Parent ParentType;
// structors
explicit ChildOf(Parent& p);
~ChildOf();
// general use
Parent& GetParent();
const Parent& GetParent() const;
void SetParent(Parent& p);
private:
// data
Parent *m_pParent;
};
/*
implementation
*/
template <class ParentType>
ChildOf<ParentType>::ChildOf(ParentType& p)
: m_pParent(&p)
{}
template <class Parent>
ChildOf<Parent>::~ChildOf()
{}
template <class ParentType>
inline
ParentType& ChildOf<ParentType>::GetParent()
{
return *m_pParent;
}
template <class ParentType>
inline
const ParentType& ChildOf<ParentType>::GetParent() const
{
return *m_pParent;
}
template <class ParentType>
void ChildOf<ParentType>::SetParent(ParentType& p)
{
m_pParent = &p;
}
Upvotes: 3
Reputation: 124997
Use a forward declaration to tell the compiler that foo2
is a class that will be defined subsequently.
class foo2;
class foo {
foo2 *child;
};
class foo2 {
foo *parent;
};
Upvotes: 0
Reputation: 12321
You should use forward declarations and include the header files in your cpp
// foo.h
#ifndef FOO_H_
#define FOO_H_
class foo2;
class foo
{
public:
foo2 *child;
};
#endif
// foo2.h
#ifndef FOO_2_H_
#define FOO_2_H_
class foo;
class foo2
{
public:
foo *parent;
};
#endif
Upvotes: 2
Reputation: 53037
You don't need to include the file if you're only using a pointer, and you won't have looping trouble if you include them in .cpp files:
// foo.h
class foo2; // forward declaration
class foo
{
public:
foo2 *child;
};
// foo2.h
class foo;
class foo2
{
public:
foo *parent;
};
//foo.cpp
#include "foo.h"
#include "foo2.h"
//foo2.cpp
#include "foo2.h"
#include "foo.h"
Although you may be better off by rethinking your design.
Upvotes: 9