Created
April 28, 2016 17:21
-
-
Save GNY-001F2/32ebf5501c6b2e3c4361a4357f4960ba to your computer and use it in GitHub Desktop.
How to fix cyclic dependencies between two header files
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** DO AS YOU PLEASE PUBLIC LICENSE | |
* Modified from the WTFPL, 2016 | |
* | |
* Copyright (C) 2016 GNY-001F2 | |
* | |
* Everyone is permitted to copy and distribute verbatim or modified | |
* copies of this license document, and changing it is allowed as long | |
* as the name is changed. | |
* | |
* DO AS YOU PLEASE PUBLIC LICENSE | |
* TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION | |
* | |
* 0. You may do whatever you please with the code contained in this file, | |
* without any restrictions except those mandated by law. | |
*/ | |
/* So you have two header files, foo.h and bar.h. In foo.h you created a class called foo_t, | |
* and in bar.h you created a class called bar_t. | |
* Unfortunately, your solution also required that you have pointers to objects of foo_t in | |
* bar_t and of bar_t in foo_t. | |
* You can't #include<[foo.h|bar.h]> in [bar.h|foo.h] because that would be a cyclic | |
* dependency. The compiler cannot resolve it due to missing symbols - it expects | |
* to know about foo_t when it compiles bar_t and about bar_t when it compiles foo_t. | |
* So instead, you can use a forward declaration of the class, and if the class is in a | |
* namespace, you need to wrap your forward declaration around it. See below for an example: | |
*/ | |
/* in your production code, always have include guards for your header files! */ | |
//foo.h | |
namespace bar { | |
typedef struct bar_t bar_t; | |
} | |
namespace foo { | |
typedef struct foo_t { | |
int fooint; | |
std::weak_ptr<bar::bar_t> barptr; | |
} foo_t; | |
} | |
//bar.h | |
namespace foo { | |
typedef struct foo_t foo_t; | |
} | |
namespace bar { | |
typedef struct bar_t { | |
char** barchar; | |
std::weak_ptr<foo::foo_t> fooptr; | |
} bar_t; | |
} | |
//impl.cpp | |
//the compiler will not create conflicts | |
#include "foo.h" | |
#include "bar.h" | |
int main() { | |
std::cout<<"This program compiled without errors."<<std::endl; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment