Well I have 2 classes in 2 header and 2 cpp files
#class1.h
#ifndef class1_h
#define class1_h
class myclass;
#endif
#class2.h
#ifndef class2_h
#define class2_h
class anotherclass;
#endif
#class1.cpp
class myclass
{
anotherclass test1;
}
#class2.cpp
class anotherclass
{
myclass test2;
}
And of course a simple main
Well I think it's obvious why this thing wont even compile
my question here is how to make it compile?
Having the classes in different files is mandatory..
If the class definitions (the bodies that is) must be in separate files then the members of the declared type can only be a pointer (or a reference but that is unusual). You would then need a function in the source file where the class is actually defined that returns a pointer-to-instance of the type.
MyClass.h:
#if !defined(MYCLASS_H)
#define MYCLASS_H
class MyClass;
MyClass * CreateMyClass();
#endif
OtherClass.h:
#if !defined(OTHERCLASS_H)
#define OTHERCLASS_H
class OtherClass;
OtherClass * CreateOther();
#endif
myclass.cpp
#include "otherclass.h"
class MyClass
{
OtherClass * ptrOther;
public:
MyClass()
: ptrOther(CreateOther())
{}
};
otherclass.cpp:
#include "myclass.h"
class OtherClass
{
MyClass * ptrMyClass;
public:
OtherClass()
: ptrMyClass(CreateMyClass())
{}
};
Note that doing things this way you would not actually be able to do anything with ptrOther or ptrMyClass ((possibly not even free them correctly), It would be much more typical to place the class definitions in the header and separate out the member definitions (for functions and statics), like the following:
MyClass2.h:
#if !defined(MYCLASS2_H)
#define MYCLASS2_H
#include "OtherClass.h"
class MyClass2
{
OtherClass * ptrOther;
public:
MyClass2();
};
#endif
cMyClass.cpp:
#include "MyClass2.h"
MyClass2::MyClass2()
: ptrOther(CreateOther())
{}
Header files define class interfaces. Source code '.cpp' files are using for the implementation. Your source code has the implementation and the class interface.
Related
I have class1 that needs header of class2.And class2 that needs header of class1 to be included.
I included header of class2 in class1 and header of class1 in class2 and troubles began (in class2 I get error that says that class1 instance do not name a class)
Please can someone explain how to deal with this situation because I googled this question but didn't get what to do
thank you
One often applicable solution to this is to simply forward-declare the classes. For example:
class1.h
#ifndef CLASS1_H
#define CLASS1_H
class Class2;
class Class1 {
public:
// ...
private:
// ...
std::unique_ptr<Class2> owned_child_;
// ...
};
#endif
class2.h
#ifndef CLASS2_H
#define CLASS2_H
class Class1;
class Class2 {
public:
// ...
private:
// ...
const Class1* unowned_parent_;
// ...
};
#endif
Note, however, that this strategy only works so long as you do not write code that requires the definition of the class to be available, which can be achieved when using pointers or references to the class's type. As soon as you use the class type without a reference or pointer, you will need to have available the full declaration of the class already processed and available.
If I'm creating a static library with a header file such as this:
// Myfile.h
#include "SomeHeaderFile.h" // External library
Class MyClass
{
// My code
};
Within my own project I can tell the compiler (in my case, Visual Studio) where to look for SomeHeaderFile.h. However, I don't want my users to be concerned with this - they should be able to include my header without having to inform their compiler about the location of SomeHeaderFile.h.
How is this type of situation normally handled?
This is a classic "compilation firewall" scenario. There are two simple solutions to do:
Forward-declare any classes or functions that you need from the external library. And then include the external library's header file only within your cpp file (when you actually need to use the classes or functions that you forward-declared in your header).
Use the PImpl idiom (or Cheshire Cat) where you forward-declare an "implementation" class that you declare and define only privately (in the cpp file). You use that private class to put all the external-library-dependent code to avoid having any traces of it in your public class (the one declared in your header file).
Here is an example using the first option:
#ifndef MY_LIB_MY_HEADER_H
#define MY_LIB_MY_HEADER_H
class some_external_class; // forward-declare external dependency.
class my_class {
public:
// ...
void someFunction(some_external_class& aRef); // declare members using the forward-declared incomplete type.
};
#endif
// in the cpp file:
#include "my_header.h"
#include "some_external_header.h"
void my_class::someFunction(some_external_class& aRef) {
// here, you can use all that you want from some_external_class.
};
Here is an example of option 2:
#ifndef MY_LIB_MY_HEADER_H
#define MY_LIB_MY_HEADER_H
class my_class_impl; // forward-declare private "implementation" class.
class my_class {
private:
std::unique_ptr<my_class_impl> pimpl; // a vanishing facade...
public:
// ...
};
#endif
// in the cpp file:
#include "my_header.h"
#include "some_external_header.h"
class my_class_impl {
private:
some_external_class obj;
// ...
public:
// some functions ...
};
my_class::my_class() : pimpl(new my_class_impl()) { };
Say the external header file contains the following:
external.h
class foo
{
public:
foo();
};
And in your library you use foo:
myheader.h:
#include "external.h"
class bar
{
...
private:
foo* _x;
};
To get your code to compile, all you have to do is to forward declare the foo class (after that you can remove the include):
class foo;
class bar
{
...
private:
foo* _x;
};
You would then have to include external.h in your source file.
this maybe a little trivial but I'm puzzled with such problem.
I want to create two classes Class1, Class2. Both classes should contain a field that contains pointer to instance of the other class. So they should be cross linked.
If I do it like this then I get an error from the compiller saying:
- ISO C++ forbids declaration of 'Class1' with no type
- expected ';' before * token
Please help :)
file: class1.h
#ifndef CLASS1_H
#define CLASS1_H
#include "class2.h"
class Class1 {
public:
Class1();
private:
Class2* link;
}
#endif
file: class2.h
#ifndef CLASS2_H
#define CLASS2_H
#include "class1.h"
class Class2 {
public:
Class2();
private:
Class1* link;
}
#endif
Add class declaration (as opposed to definition) before you use it. For example, you could have:
#ifndef CLASS1_H
#define CLASS1_H
class Class2;
class Class1
{
public:
Class1();
private:
Class2* link;
}
#endif
and do the same for Class2.h.
The problem is the circular dependency; each header is trying to include the other, which is impossible.
You don't need the full definition of each class in order to declare a pointer to it; you can replace each #include line with a forward declaration (class Class1; and class Class2;), and then everything should compile happily.
I have two classes and both of them uses some of the other class, on example:
// class1.h
class Class1;
#include "class2.h"
class Class1 {
public:
static Class2 *C2;
...
};
// class2.h
class Class2;
#include "class1.h"
class Class2 {
public:
static Class1 *C1;
...
};
And when I define it like in example above, it works (I also have some #ifndef to avoid infinite header recurency). But I also want to add some inline functions to my classes. And I read here that I should put definition of inline function in header file, because it won't work if I'll put them in cpp file and want to call them from other cpp file (when I do it I get undefined reference during linking). But the problem here is with something like this:
// class1.h
...
inline void Class1::Foo() {
C2->Bar();
}
I get error: invalid use of incomplete type ‘struct Class2’.
So how can I do it?
You need to delay including the header, but then include it and define your inline methods. By doing this in each header, they are self-sufficient and including one will always include the other, with include guards preventing infinite recursion.
A.hpp
#ifndef INCLUDE_GUARD_B9392DB18D114C1B8DFFF9B6052DBDBD
#define INCLUDE_GUARD_B9392DB18D114C1B8DFFF9B6052DBDBD
struct B;
struct A {
B* p;
void foo();
};
#include "B.hpp"
inline
void A::foo() {
if (p) p->bar();
}
#endif
B.hpp
#ifndef INCLUDE_GUARD_C81A5FEA876A4C6B953D1EB7A88A27C8
#define INCLUDE_GUARD_C81A5FEA876A4C6B953D1EB7A88A27C8
struct A;
struct B {
A* p;
void bar();
};
#include "A.hpp"
inline
void B::bar() {
if (p) p->foo();
}
#endif
You have it mix'd up. What you want is:
// class1.h
class Class2;
class Class1 {
public:
static Class2 *C2;
...
};
// class2.h
class Class1;
class Class2 {
public:
static Class1 *C1;
...
};
And include the respective headers in the source. The line:
class Class1; // or Class2
Declares an incomplete type, and you can have pointers and references to incomplete types. Upon usage, though, it needs to be complete. So just say "hey it'll exist!" in the header, and in the source tell it what it is.
My suggestion is that you place common methods and members into a base class, then derive C1 and C2 from the base class. This may fix the circular dependency issue.
This question already has answers here:
Resolve build errors due to circular dependency amongst classes
(12 answers)
Closed 4 years ago.
FILE #1 (foo.h):
#ifndef FOO_H_
#define FOO_H_
#include "baseclass.h"
#include "bar.h"
class Bar;
class Foo : public baseclass {
public:
bar *varBar;
};
#endif
FILE #2 (bar.h):
#ifndef BAR_H_
#define BAR_H_
#include "foo.h"
class Foo;
class Bar {
public:
Foo *varFoo;
};
#endif
FILE #3 (baseclass.h):
#ifndef BASECLASS_H_
#define BASECLASS_H_
#include "foo.h"
class Foo;
class baseclass {
public:
list<Foo*> L;
};
#endif
But I get an compile error in file #1 in line class Foo : public baseclass:
Error: expected class-name before »{« token
If I add class baseclass; bevor class declaration, I get this error:
Error: invalid use of incomplete type »struct baseclass«
So my question is, how can I resolve circular dependencies with baseclasses?
Ask if you don't get somepoint. I allready tried to change the order of includeing the headers, but no luck so far.
Thanks for any hint.
EDIT: Note: I am using include guards
EDIT2: It is not limited to pointers, so I remove them, just in case.
EDIT3: Added baseclass (forgot O.o)
EDIT4: Now it should be clear and without anymore flaws, the problem persisits with this code.
The usual way is to add the following around your header files:
#ifndef FOO_H_
#define FOO_H_
#include "baseclass.h"
#include "bar.h"
class Bar;
class Foo : public baseclass {
public:
bar *varBar;
};
#endif
and
#ifndef BAR_H_
#define BAR_H_
#include "foo.h"
class Foo;
class Bar {
public:
Foo *varFoo;
};
#endif
Most compilers (gcc, VC) also accept #pragma once at the beginning of the file, but I'm pretty sure it is not part of the current C++ standard.
EDIT:
Sure enough, as the ISO/IEC 14882 states, a #pragma "causes the implementation to behave in an implementation-defined manner. Any pragma that is not recognized by the implementation is ignored."
It is currently still the same with C++0x.
So I would stick with the first old-fashioned way of doing that ;-)
What you seem to have posted is to have a Bar member in the Foo, and a Foo member in the Bar. That is a circular dependency you need to break - if every Foo contains a Bar which contains a Foo then constructing either never terminates.
class Foo : public baseclass {
public:
Bar varBar;
};
class Bar {
public:
Foo varFoo;
};
Instead you need to use a pointer or reference to the Foo or Bar in at least one of them:
class Bar;
class Foo : public baseclass {
public:
Bar& varBar;
};
class Bar {
public:
Foo varFoo;
};
As the circularity is broken and you're only using a reference to the object, you don't need to have the full definition of the referred-to type, and can use a forward declaration.
Include guards are good for users, but try and not rely on them when developing. If the compiler has to check whether or not something has been included, it's still doing work even if it has optimisations for guards/pragmas. You do need to have some understanding of what depends on what to break the initial cycle, and putting guards on the files won't help you with that.
Do you have include guards on your headers? The code above includes a.h and b.h recursively, thus defining a whole bunch of headers.
The forward declaration class b; removes the need for the #include "b.h" in FILE1. Similarly, #include "a.h" should be removed from FILE2.
#ifndef _BAR_H_
#define _BAR_H_
#include "baseclass.h"
class Bar;
class Foo : public baseclass {
public:
Bar *varBar;
};
#endif
If a class is forward declared and you are using only a pointer or a reference to a member of that class, then you do not need to include the header for it. The same goes for the class in the other file. But yes, make sure that you use include guards in all of your header files (#ifndef...#endif) to prevent multiple inclusions of headers during compilation.
baseclass.h doesn't need anything from foo.h, so remove #include "foo.h" from baseclass.h.
You have a Foo variable in your Bar, and a Bar in your Foo. That isn't going to work: you can't have an egg in a box and a box in an egg. One or both of them should be a pointer.