How to have two classes with each as a data member of the other?

For example, this will result in error:

1
2
3
4
5
6
7
8
9
10
11
class Girl 
{ 
    public: 
        Guy boyfriend;
}

class Guy 
{ 
    public: 
        Girl girlfriend;
}


Declarining Girl girlfriend within class Guy is alright, but I also want to declare Guy boyfriend in class Girl, but I can't do that because one class must always be declared before the other. What's the way around this?
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14

class Guy;  // forward declaration

class Girl 
{ 
    public: 
        Guy boyfriend;
}

class Guy 
{ 
    public: 
        Girl girlfriend;
}
Use rererences, pointers or reference_wrappers as appropriate.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Girl ;
class Guy ;

class Girl
{
    // ...

    public:
        Guy& boyfriend_r ;
        Guy* boyfriend_p ;
        std::reference_wrapper<Guy> boyfriend_w ;
};

class Guy
{
    // ...

    public:
        Girl& girlfriend_r ;
        Girl* girlfriend_p ;
        std::reference_wrapper<Girl> girlfriend_w ;
};


If a Girl will always have the same boyfriend, use a reference.
If a Girl may sometimes not have a boyfriend, use a (if appropriate, smart) pointer.
If a Girl will always have a boyfriend, but it may be a different boyfriend at different points in time, use a reference_wrapper.
Last edited on
I tried that. It gives error at the line
std::reference_wrapper<Guy> boyfriend_w ;

I even tried compiling what you wrote above and nothing else:
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
28
29
30
31
32
33
34
#include <iostream> 
using namespace std; 

class Girl ;
class Guy ;

class Girl
{
    // ...

    public:
        Guy& boyfriend_r ;
        Guy* boyfriend_p ;
        std::reference_wrapper<Guy> boyfriend_w ;
};

class Guy
{
    // ...

    public:
        Girl& girlfriend_r ;
        Girl* girlfriend_p ;
        std::reference_wrapper<Girl> girlfriend_w ;
}; 




int main( )
{   
    cout << "Testing" << endl;
    return 0;
}

Last edited on
#include <functional> And compile as C++11.

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
28
29
30
31
32
33
#include <functional>
#include <string>
#include <iostream>

struct Guy ;

struct Girl
{
    Girl( Guy& g ) : boyfriend(g) {}
    std::reference_wrapper<Guy> boyfriend ;
};

struct Guy
{
    const std::string name ;
  // ...
};

int main()
{
    Guy a { "a" };

    Girl b(a) ;
    std::cout << b.boyfriend.get().name << '\n' ;

    Guy c { "c" } ;
    b.boyfriend = c ;
    std::cout << b.boyfriend.get().name << '\n' ;

    Guy no_one { "no one" };
    b.boyfriend = no_one ;
    std::cout << b.boyfriend.get().name << '\n' ;
}

http://ideone.com/1QKNpu

Or, just use a pointer.

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
28
29
30
31
32
#include <string>
#include <iostream>

struct Guy ;

struct Girl
{
    Girl( Guy* g = 0 ) : boyfriend(g) {}
    Guy* boyfriend ;
};

struct Guy
{
    Guy( const std::string& n ) : name(n) {}
    const std::string name ;
    // ...
};

int main()
{
    Guy a( "a") ;

    Girl b( &a ) ;
    if( b.boyfriend ) std::cout << b.boyfriend->name << '\n' ;

    Guy c( "c" ) ;
    b.boyfriend = &c ;
    if( b.boyfriend ) std::cout << b.boyfriend->name << '\n' ;

    b.boyfriend = 0 ;
    if( b.boyfriend ) std::cout << b.boyfriend->name << '\n' ;
}

http://ideone.com/cq9m0l
Last edited on
This looks a good start for me (apparently I still need to understand better pointers). Is it easy to modify the code if the girl can have multiple boyfriends at the same time (let's say up to 5 simultaneous boyfriends)? I tried putting an array there, but I guess I still don't understand the language/syntax enough to make that work.
> Is it easy to modify the code if the girl can have multiple boyfriends at the same time

Use a std::vector<> http://www.mochima.com/tutorials/vectors.html

Something like this (C++98):

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
28
29
30
31
32
33
34
35
36
#include <iostream>
#include <vector>

struct Guy ;

struct Girl
{
    std::vector<Guy*> boyfriends ;
};

struct Guy
{
    Guy( const std::string& n ) : name(n) {}
    const std::string name ;
    // ...
};

int main()
{
    Guy a( "a" ), b( "b" ), c( "c" ) ;

    Girl g ;

    g.boyfriends.push_back( &a ) ;
    g.boyfriends.push_back( &b ) ;

    for( std::size_t i = 0 ; i < g.boyfriends.size() ; ++i )
        std::cout << g.boyfriends[i]->name << ' ' ;
    std::cout << '\n' ;

    g.boyfriends.push_back( &c ) ;

    for( std::size_t i = 0 ; i < g.boyfriends.size() ; ++i )
        std::cout << g.boyfriends[i]->name << ' ' ;
    std::cout << '\n' ;
}

http://ideone.com/xkmbmN
Thank you so much for your help, JLBorges. Now I'm getting somewhere.
Topic archived. No new replies allowed.