How do I create co-dependant namespaces.

I have the following namespaces:

A.h + A.cpp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#ifndef INHERITANCE_A_H
#define INHERITANCE_A_H

#include <string>
#include <iostream>
#include "B.h"

namespace A {
    int j = 12;

    void foo();
    void qux();
};


#endif //INHERITANCE_A_H

#include "A.h"

void A::foo(){
    std::cout << "A::foo called \n";
    B::bar();
}

void A::qux(){
    std::cout << "A::qux called\n";
}


B.h + B.cpp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#ifndef INHERITANCE_B_H
#define INHERITANCE_B_H

#include <string>
#include <iostream>
#include "A.h"

namespace B {
    int i = 12;

    void bar();
    void baz();
};


#endif //INHERITANCE_B_H

#include "B.h"
void B::bar(){
    std::cout << "B::bar called\n";
    baz();
}

void B::baz(){
    std::cout << "B::baz called\n";
    A::qux();
}


These classes are co-dependant on each other i.e they both call functions that reside in the other. Now do you see those namespaced variables A:j and B:i (they are both on line 9 of each header file, both set to an int of 12)? If I comment them out the code runs as expected:

1
2
3
4
5
6
7
int main() {
    A::foo(); // --> outputs A::foo called 
              //             B::bar called
              //             B::baz called
              //             B::qux called

}


However, the second I uncomment those namespaced variables I get this:

1
2
3
4
5
6
7
8
9
CMakeFiles/Inheritance.dir/A.cpp.o:A.cpp:(.data+0x0): multiple definition of `B::i'
CMakeFiles/Inheritance.dir/main.cpp.o:main.cpp:(.data+0x0): first defined here
CMakeFiles/Inheritance.dir/A.cpp.o:A.cpp:(.data+0x4): multiple definition of `A::j'
CMakeFiles/Inheritance.dir/main.cpp.o:main.cpp:(.data+0x4): first defined here
CMakeFiles/Inheritance.dir/B.cpp.o:B.cpp:(.data+0x0): multiple definition of `A::j'
CMakeFiles/Inheritance.dir/main.cpp.o:main.cpp:(.data+0x4): first defined here
CMakeFiles/Inheritance.dir/B.cpp.o:B.cpp:(.data+0x4): multiple definition of `B::i'
CMakeFiles/Inheritance.dir/main.cpp.o:main.cpp:(.data+0x0): first defined here
collect2: error: ld returned 1 exit status


How should I stucture my code so two namespaces can call on each other but their variables are only set once and so my code compiles? Should I turn one of them into a class? Worth noting I am pretty new to C++

Thankyou very much for your help!
Last edited on
Most variables that are not inline may not be defined in a header file. Because the contents of each header file are blindly pasted in every source file that contains it, the situation here is as-if you tried to link two source files that each declared the same symbols.

To declare a non-const namespace-scope variable in a header file, define it inline (since C++17), or declare it extern and define that variable in exactly one source file.

In your case: inline int i = 12;

Don't rely on transitive includes:

In a header file, include each header that is required for the header file, and nothing more.
In a source file, include the corresponding header first, followed by every header that is required for the source file, and nothing more.
Last edited on
to clarify the last part,
there is no reason for A.h to include B.h
and neither for B.h to include A.h

however, B.cpp should include both B.h and A.h
same as A.cpp
Registered users can post here. Sign in or register to post.