Inclusion problem - c++

I have an inclusion pattern as follows:
/*
* Class1.h
*/
#ifndef CLASS1_H_
#define CLASS1_H_
#include "Class2.h"
namespace Class1_namespace
{
class Class1
{
Class2* Class2_ptr;
void Class1_member()
{
(*Class2_ptr).Class2_method();
}
};
}
#endif /* CLASS1_H_ */
/*
* Class2.h
*/
#ifndef CLASS2_H_
#define CLASS2_H_
#include "Class1.h"
class Class2
{
Class1_namespace::Class1 Class2_data;
public:
void Class2_method(){};
};
#endif /* CLASS2_H_ */
/*
* main.cpp
*/
#include "Class1.h"
int main()
{
return 0;
}
However, this leads to the error “'Class1_namespace' does not name a type.”
Is this error caused by the ordering of my inclusions?
What are some possible solutions? I'm dubious about forward declarations solving my problem.

Class1 doesn't need to include Class2.
When you have mutual dependency (which you don't -- you could just not include 2 in 1), you can usually solve it by using forward declarations instead of inclusions.
For example, let's say that Class1 looked like this
#include "Class2.h"
namespace Class1_namespace
{
class Class1
{
Class2* class2;
};
}
Where you think you need the include, you could instead do this:
class Class2;
namespace Class1_namespace
{
class Class1
{
Class2* class2;
};
}
to break the mutual inclusion.

In class1.h, try removing the unnecessary and circular #include of class2.h. If a circular dependency is required -- or even if not -- consider using forward declarations.

Related

Use a function in one class in other without inheritance in c++

The situation is like this:
//header file
#ifndef CLASSA_H
#define CLASSA_H
#include <stdint.h>
class ClassA
{
public:
void function1();
void function2();
};
#endif //CLASSA_H
//cpp file
#include "ClassA.h"
void ClassA::function1()
{
/* some code */
}
void ClassA::function2()
{
/* some more code */
}
void function3()
{
/* more code /*
}
//main.cpp
#include "ClassA.h"
int main()
{
ClassA obj;
obj.function3();
}
I want to call function3() in main.cpp but without inheritance. I tried using the instance of ClassA but that says "function3 is not a member of classA".
Maybe I'm missing a concept, would be great if anyone can help.
When you try to call function3() with obj.function3() syntax, the compiler then tries to find if there's a function exists named function3 in the instance of the class (i.e. object).
Now, in this case, you can do two things:
Include void function3() in the public: of the class and change void function3() to void ClassA :: function3() to tell the compiler that the containing code is defined for the class member function.
Or, define the function inside the header file and prevent calling the function by defining the class object. It's obvious, isnce you can't access something which is declared outside of the class.
The code explanation of all the two above methods is as follows:
Method 1
ClassA.cpp
#include "ClassA.h"
...
void ClassA::function3() // definition of the class member function
{
/* more code */
}
main.cpp
#include "ClassA.h"
int main()
{
ClassA obj;
obj.function3(); // now it's inside the class member function
// hence, we may now use it
}
ClassA.h
...
class ClassA
{
public:
...
void function3(); // declared inside the class
};
#endif //CLASSA_H
Method 2
ClassA.h
...
void function3()
{
/* more code */
}
main.cpp
#include "ClassA.h"
int main()
{
function3();
}
ClassA.cpp
class {
...
};
void function3()
{
/* more code */
}
But the second method will make the class useless, therefore, possibly you meant to achieve the first method and not the second.

Circular inclusion with function inside namespace

I'm starting to learn C++ and recently encountered a problem with circular dependency of two headers.
I've already tried forward declaring the Class and namespace, also played around with it in a seperate project but didn't find any solution. Whatever I do the function doesn't get access to the class private members.
Here i simplified the problem a little bit.
A.h
#pragma once
#include "B.h"
class Player {
private:
int m_number;
public:
friend void Byte::getDataChunk(Player& p);
};
B.h
#pragma once
#include <iostream>
#include "A.h"
class Player;
namespace Byte {
void doOtherStuff() {
//other Stuff
}
void getDataChunk(Player& p) {
std::cout << p.m_number;
doOtherStuff();
}
}
I would really like to keep the class and namespace in seperate files, but I don't see any way of doing it. Thanks for your help in advance!
You need to change A.h to include a forward declaration of getDataChunk() in namespace Byte:
#pragma once
#include "B.h"
class Player;
namespace Byte {
void getDataChunk(Player& p);
}
class Player {
private:
int m_number;
public:
friend void Byte::getDataChunk(Player& p);
};
Please note also that including function definitions in header files (i.e. getDataChunk() in B.h) is going to cause you headaches.

circular class dependency within template member

#ifndef CLASSB
#define CLASSB
#include "ClassA.h"
namespace name {
class ClassB
{
public:
static Handle conn();
};
}
#endif
-
#include "ClassB.h"
Handle name::ClassB::conn()
{
return getHandle(ClassA::it().str());
}
-
#ifndef CLASSA
#define CLASSA
#include "ClassB.h"
namespace name {
class ClassA
{
public:
template <typename T>
T myFunc(const std::string&)
{
auto tmp = ClassB::conn();
}
};
}
#endif
Calling ClassB::conn() gives a compiler error which says that the class ClassB is not declared. When I forward declare it I get an error message about an incomplete type.
I can't move the template function to my .cpp files as it is a template function. So, how to fix this?
Just remove #include "ClassA.h" from class B's header and it should work. But there appear to be multiple compilation problems with your code so it's hard to say (missing function getHandle, missing it(), missing type Handle etc).

C++ linking 2 classes together how

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.

Two classes and inline functions

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.