Background: I am working on a framework that generates C++ code based on an existing Java class model. For this reason I cannot change the circular dependency mentioned below.
Given:
- A Parent-Child class relationship
- Parent contains a list of Children
- Users must be able to look up the list element type at run-time
I’ve modeled this in the following testcase:
Main.cpp
#include "Parent.h"
#include <iostream>
using std::cout;
using std::endl;
int main(int argc, char* argv[])
{
Parent parent;
cout << Parent::getType() << endl;
cout << parent.getChildren().getType() << endl;
return 0;
}
Parent.h
#ifndef PARENT_H
#define PARENT_H
#include <string>
#include "Array.h"
class Child;
class Parent
{
public:
Array<Child> getChildren()
{
return Array<Child>();
}
static std::string getType()
{
return "parent";
}
};
#endif
Child.h
#ifndef CHILD_H
#define CHILD_H
#include "Parent.h"
class Child: public Parent
{
};
#endif
Array.h
template <typename ElementType>
class Array
{
public:
static std::string getType()
{
return ElementType::getType();
}
};
-
When I compile the above code I get:
error C2027: use of undefined type 'Child'atreturn ElementType::getType(); -
If I try
#include "Child.h"instead of the forward declaration I get:
error C2504: 'Parent' : base class undefinedatclass Child: public Parent -
If I try
Array<Child*>instead ofArray<Child>I get:
error C2825: 'ElementType': must be a class or namespace when followed by '::'atreturn ElementType::getType();
The circular dependency comes about because:
- Child.h needs to know about class Parent
- Parent.h needs to know about class Array
- Array.h needs to know about class Child
Any ideas?
The error is due to the Child class not being present when the template is instantiated.
Add the following either to Main or at the end of Parent.h:
This compiles fine with both g++ 4 and VS 2010.