Class Inclusion

Hello,

I've got a - I believe - pretty common problem but I can't figure it out. I've got two different classes which I want both to hold an instance of each other. Here's my code;

main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
#include "MyClass1.cpp"
#include "MyClass2.cpp"

int main()
{
    MyClass1 c1;
    MyClass2 c2;

    c1.setC2(&c2);
    c2.setC1(&c1);

    return 0;
}


MyClass1.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class MyClass2;

class MyClass1
{
private:

    MyClass2 *m_c2;

public:

    void setC2(MyClass2 *c) { m_c2 = c; }

    int getC2Number() { return m_c2->returnNumber(); }

    int returnNumber() { return 100; }
};


MyClass2.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class MyClass1;

class MyClass2
{
private:

    MyClass1 *m_c1;

public:

    void setC1(MyClass1 *c) { m_c1 = c; }

    int getC1Number() { return m_c1->returnNumber(); }

    int returnNumber() { return 200; }
};


A number of solutions to a similar problem is found here;

http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.13

But, I can't get this to work for my situation since the classes are trying to get access to each other.

This is actually a simplification of my real problem. When creating a 'big' application like, for example, a game, one would create multiple classes like a spritemanager, soundmanager, field, camera etc. My idea was to create a 'superclass' which holds pointers of all classes. So for example, in the camera class I could call Super->Field->DoSomething(). The camera class has a pointer to the superclass, and the superclass has a pointer to the field class, but also to the camera class (which is exactly the situation I simplified above).

So, is there a solution to the simplified problem? If not or if it's too complicated, how else would I manage the above described situation? How do classes interact with each other while it's so hard to have them keep instances of each other?
I take it the classes are declared in .h files rather than .cpp files.

The forward declarations should be fine. Just don't use inline methods. Define the methods in a .cpp file and include both .h files.
I rewrote it to using .h and .cpp files, but I'm getting the same error. These are the exact errors I'm getting:

MyClass1.cpp||In member function `int MyClass1::getC2Number()':|
MyClass1.cpp|8|error: invalid use of undefined type `struct MyClass2'|
MyClass1.h|4|error: forward declaration of `struct MyClass2'|

The error happens when MyClass1 tries to access a function from MyClass2. Here's the new code;

main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
#include "MyClass1.h"
#include "MyClass2.h"

int main()
{
    MyClass1 c1;
    MyClass2 c2;

    c1.setC2(&c2);
    c2.setC1(&c1);

    return 0;
}


MyClass1.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#ifndef INC_MYCLASS1_HPP
#define INC_MYCLASS1_HPP

class MyClass2;

class MyClass1
{
private:

    MyClass2 *m_c2;

public:

    void setC2(MyClass2 *c);

    int getC2Number();

    int returnNumber();
};

#endif 


MyClass2.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#ifndef INC_MYCLASS2_HPP
#define INC_MYCLASS2_HPP

class MyClass1;

class MyClass2
{
private:

    MyClass1 *m_c1;

public:

    void setC1(MyClass1 *c);

    int getC1Number();

    int returnNumber();
};

#endif 


MyClass1.cpp
1
2
3
4
5
6
7
8
9
10
11
12
#ifndef INC_MYCLASS1_CPP
#define INC_MYCLASS1_CPP

#include "MyClass1.h"

void MyClass1 :: setC2(MyClass2 *c) { m_c2 = c; }

int MyClass1 :: getC2Number() { return m_c2->returnNumber(); }

int MyClass1 :: returnNumber() { return 100; }

#endif 


MyClass2.cpp
1
2
3
4
5
6
7
8
9
10
11
12
#ifndef INC_MYCLASS2_CPP
#define INC_MYCLASS2_CPP

#include "MyClass2.h"

void MyClass2 :: setC1(MyClass1 *c) { m_c1 = c; }

int MyClass2 :: getC1Number() { return m_c1->returnNumber(); }

int MyClass2 :: returnNumber() { return 200; }

#endif 
Last edited on
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include "C1.h"
#include "C2.h"
#include <iostream>

int main()
{
    C1 c1;
    std::cout << c1.OtherName() << std::endl;

    C2 c2;
    std::cout << c2.OtherName() << std::endl;

    return 0;
}


C1.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#pragma once

#include <string>

class C2;

class C1
{
    C2* other;

    C1(const C1 &);
    C1& operator=(const C1 &);

public:
    C1();
    ~C1();

    std::string Name() const;
    std::string OtherName() const;
};


C2.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#pragma once

#include <string>

class C1;

class C2
{
    C1* other;
 
    C2(const C2 &);
    C2& operator=(const C2 &);

public:
    C2();
    ~C2();
    std::string Name() const;
    std::string OtherName() const;
};


C1.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include "C1.h"
#include "C2.h"

C1::C1()
    :    other(new C2)
{
}

C1::~C1()
{
    delete other;
}

std::string C1::Name() const
{
    return "C1";
}

std::string C1::OtherName() const
{
    return other->Name();
}


C2.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include "C2.h"
#include "C1.h"

C2::C2()
   :   other(new C1)
{
}

C2::~C2()
{
    delete other;
}

std::string C2::Name() const
{
    return "C2";
}

std::string C2::OtherName() const
{
    return other->Name();
}
kbw:
have you tried this compiling.. because i think this might not work.. there was a similar post somewhere i found today.. Bazzy said the same thing which you have said.. but somewhere i've a doubt on this..

so thats why asking if you tried compiling it.?
ok.. its working.. :)
i compiled it.
Topic archived. No new replies allowed.