C++ Circular Dependency in Header Files - c++

Is it possible to avoid circular dependency in the following header files without turning data member b1 in class A to a pointer/reference, and without relaxing the inline function requirement in class B?
A.h:
#ifndef A_H
#define A_H
#include <B.h> // Required, as data member b1 is not a pointer/reference
class A {
public:
B b1; // I want to keep this as as it is.
int m_a;
};
#endif
B.h:
#ifndef B_H
#define B_H
#include <A.h> // Required, as f() calls a member function of class A
class B {
public:
int f(A &a){return a.m_a;} // I want this to be an inline function.
};
#endif
...and let's say main.ccp is:
#include <iostream>
#include <A.h>
#include <B.h>
int main() {
A a;
B b;
std::cout << "Calling b.f(a): " << b.f(a) << std::endl;
return 0;
}

You could use this:
A.h
#include <B.h>
#ifndef A_H
#define A_H
class A
{
public:
B b1;
int m_a;
};
#endif // A_H
B.h
#ifndef B_H
#define B_H
class A;
class B
{
public:
int f(A &a);
};
#include <A.h>
inline int B::f(A &a)
{
return a.m_a;
}
#endif // B_H
main.cpp
#include <iostream>
#include <A.h> // these could be in any order
#include <B.h>
int main()
{
A a;
B b;
std::cout << "Calling b.f(a): " << b.f(a) << std::endl;
return 0;
}

Related

C++ Class members recursive pointers? I guess [duplicate]

Is it possible to avoid circular dependency in the following header files without turning data member b1 in class A to a pointer/reference, and without relaxing the inline function requirement in class B?
A.h:
#ifndef A_H
#define A_H
#include <B.h> // Required, as data member b1 is not a pointer/reference
class A {
public:
B b1; // I want to keep this as as it is.
int m_a;
};
#endif
B.h:
#ifndef B_H
#define B_H
#include <A.h> // Required, as f() calls a member function of class A
class B {
public:
int f(A &a){return a.m_a;} // I want this to be an inline function.
};
#endif
...and let's say main.ccp is:
#include <iostream>
#include <A.h>
#include <B.h>
int main() {
A a;
B b;
std::cout << "Calling b.f(a): " << b.f(a) << std::endl;
return 0;
}
You could use this:
A.h
#include <B.h>
#ifndef A_H
#define A_H
class A
{
public:
B b1;
int m_a;
};
#endif // A_H
B.h
#ifndef B_H
#define B_H
class A;
class B
{
public:
int f(A &a);
};
#include <A.h>
inline int B::f(A &a)
{
return a.m_a;
}
#endif // B_H
main.cpp
#include <iostream>
#include <A.h> // these could be in any order
#include <B.h>
int main()
{
A a;
B b;
std::cout << "Calling b.f(a): " << b.f(a) << std::endl;
return 0;
}

C++ nested class instances

What I have is 2 classes:
A.h:
#include "B.h"
class A
{
vector<B*> arr;
void Update(int32 id){...};
}
B.h
#include "A.h"
class B
{
int32 id;
A* parent;
void OnRemove()
{
...
parent->Update(id);
}
}
With that logic everything must work fine as expected.
But it won't because of loop include: A.h including B.h and B.h including A.h
The question is how to make it working with that structure of code or other.
Main feature that should exist is to call event in A object which is holding B object.
Every help would be appreciated.
Forward declare class A; in B.h and class B; in A.h
You should then move the implementation of onRemove() to B.cpp and include A.h here.
Also don't forget your include guards. Example:
#ifndef _A_H_
#define _A_H_
class B;
class A {
};
#endif
The include guards could also be replaced by #pragma once at the beginning of the header, this is a little less verbose.
Edit
To be complete:
// A.h
#pragma once
#include <vector>
class B;
class A {
std::vector<B*> arr;
public:
void Update(int32 id);
};
// A.cpp
#include "A.h"
// possibly #include "B.h" if necessary
void A::Update(int32 id) {
// impl ...
}
// B.h
#pragma once
class A;
class B
{
int32 id;
A* parent;
public:
void OnRemove();
};
// B.cpp
#include "B.h"
#include "A.h"
void B::OnRemove() {
parent->Update(id);
}
Well, something like this...
the usual way is to provide guarding macros to prevent recursion and move definition of functions in a separate file if needed:
a.h
#ifndef _A_H_
#define _A_H_
#include "B.h"
class A
{
vector<B*> arr;
void Update(int32 id){...};
}
#endif
...
c.cpp (if needed)
#include <a.h>
#include <b.h>
void B::onRemove() {
blahblahblah
}

Segfault in constructor with keyword this

A.h
#ifndef A_H
#define A_H
#include "B.h"
class A{
public:
B* b;
A(){
b->ownership = this;
};
};
#endif
B.h
#ifndef B_H
#define B_H
class A;
class B{
public:
A* ownership;
};
#endif //B_H
main.cpp
#include "A.h"
class C{
A a1;
A a2;
};
int main()
{
C c;
return 0;
}
Commands:
g++ -g main.cpp -o main
./main
This program fails with segmentation fault.
"gdb main core" told me that error was in string: "b->ownership = this;"
Question: Where is my fault? What I should know not to make more of these errors? Thank you.
The problem is in this class:
class A
{
public:
B* b;
A()
{
b->ownership = this;
}
};
You're dereferencing b but you haven't created an instance of B.

Cyclic dependency in Eclipse CDT

I know this matter doesn't get enough attention because it's not meet often but I want to clarify it.
Say I have 3 files:
A.h
#ifndef A_h
#define A_h
#include "B.h"
class A {
A();
virtual ~A();
bool someFunc(B& b);
};
#endif
B.h
#ifndef B_h
#define B_h
#include "A.h"
class B {
B();
virtual ~B();
bool someFunc(A& a);
};
#endif
and main.cpp
#include "A.h"
#include "B.h"
int main() { return 0; }
without the protection (#ifndef X_h #define X_h) there is a Cyclic dependency. Adding the protection should solve the problem but when the code is compiled first main.cpp tries to include a.h which tries to include b.h before a is declared and that returns an error. If we change the code to:
A.h
#ifndef A_h
#define A_h
class A {
A();
virtual ~A();
#include "B.h"
bool someFunc(B& b);
};
#endif
B.h
#ifndef B_h
#define B_h
class B {
B();
virtual ~B();
#include "A.h"
bool someFunc(A& a);
};
#endif
Now the Cyclic dependency is solved but and the code compiles without error but still Eclipse returns an error: "Type 'B' could not be resolved" in A.h so you need to add surpress to both A.h and B.h where the other one is used. I want to know if there is another way to solve the Cyclic dependency without Eclipse returning an error and how should the code look if we have more than two classes (A includes B, C and D; B includes A, C, D ...)
As long as you don't actually use instance of class B in class A and the other way around, and only declare functions taking pointers or references, you can get away without including at all, and only declare the classes:
In file A.h
#ifndef A_h
#define A_h
class B; // Declare class B
class A {
A();
virtual ~A();
bool someFunc(B& b);
};
#endif
and in B.h
#ifndef B_h
#define B_h
class A; //Declare class A
class B {
B();
virtual ~B();
bool someFunc(A& a);
};
#endif
In the source files where the functions are defined (implemented) you of course needs to include both files.

undefined reference to a static function

I have a strange problem when I create a static function in class A and I want to call it from class B function. I get
undefined reference to `A::funcA(int)'
Here is my source code :
a.cpp
#include "a.h"
void funcA(int i) {
std::cout << i << std::endl;
}
a.h
#ifndef A_H
#define A_H
#include <iostream>
class A
{
public:
A();
static void funcA( int i );
};
#endif // A_H
b.cpp
#include "b.h"
void B::funcB(){
A::funcA(5);
}
and b.h
#ifndef B_H
#define B_H
#include "a.h"
class B
{
public:
B();
void funcB();
};
#endif // B_H
I'm compiling with Code::Blocks.
#include "a.h"
void funcA(int i) {
std::cout << i << std::endl;
}
should be
#include "a.h"
void A::funcA(int i) {
std::cout << i << std::endl;
}
Since funcA is a static function of your class A. This rule applies both to static and non-static methods.
You forgot to prefix the definition with the class name :
#include "a.h"
void A::funcA(int i) {
^^^
//Add the class name before the function name
std::cout << i << std::endl;
}
The way you did things, you defined an unrelated funcA(), ending up with two functions (namely A::funcA() and funcA(), the former being undefined).