I’m having trouble putting together an object model that involves nested classes, using MinGW C++. Here is an example that exposes my issue:
foo.h:
/*
* foo.h
*
* Created on: Sep 25, 2011
* Author: AutoBot
*/
#ifndef FOO_H_
#define FOO_H_
class Foo
{
public:
class Bar;
Bar bar;
} extern foo;
#endif /* FOO_H_ */
bar.h:
/*
* bar.h
*
* Created on: Sep 25, 2011
* Author: AutoBot
*/
#ifndef BAR_H_
#define BAR_H_
#include <iostream>
using namespace std;
#include "foo.h"
class Foo::Bar
{
public:
void Test() {cout <<"Test!";}
};
#endif /* BAR_H_ */
main.cpp:
/*
* main.cpp
*
* Created on: Sep 25, 2011
* Author: AutoBot
*/
#include "foo.h"
Foo foo;
int main (int argc, char *argv[])
{
foo.bar.Test();
return 0;
}
Eclipse CDT build log:
**** Build of configuration Debug for project NestedClassTest ****
**** Internal Builder is used for build ****
g++ -O0 -g3 -Wall -c -fmessage-length=0 -o src\main.o ..\src\main.cpp
In file included from ..\src\main.cpp:10:0:
..\src\/foo.h:15:6: error: field 'bar' has incomplete type
..\src\main.cpp: In function 'int main(int, char**)':
..\src\main.cpp:16:6: error: 'class Foo' has no member named 'bar'
Build error occurred, build is stopped
Time consumed: 171 ms.
So essentially it’s failing to recognize the definition of bar I made in bar.h. Is this normal? Why shouldn’t I be able to define nested classes this way? Is this simply a limitation of the MinGW toolchain? Any help/advice is appreciated.
Side note: in my actual program, I intend for the “foo” of it to serve as, theoretically, a singleton class. It would represent the application as a whole, and it’s subsystems (or “bars”) would be defined and instantiated once inside the class. I’m doing this to try to make the code more manageable. If anyone has a more feasible design pattern in mind, please tell me!
The problem is here:
At this point
Foo::Baris an incomplete type. And you cannot declare a variable of an incomplete type. It would be no different from trying to do this:They’re both not allowed and for the same reason.
You could turn
barinto some kind of (smart) pointer. But that’s the only way to solve this.