Classes & References

closed account (10oTURfi)
(Attention: Crappy explaination)
I need 2 classes to hold references to each other.

Ima show example:

1
2
3
4
5
6
7
8
9
class Foo
{
    Bar &refBar;
}
//...
class Bar
{
    Foo &refFoo;
}


It is to my understanding that only way for a class to have a reference to other class would be this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Foo
{
    Bar &refBar;
public:
    Foo(Bar &refBar);
}

class Bar
{
    Foo &refFoo;
public:
    Bar(Foo &refFoo);
}

Foo::Foo(Bar &refBar) : refBar(refBar)
{
}

MyFunction()
{
    Bar leBar;
    Foo leFoo(leBar);
}


Now, how do I exactly store reference to leFoo in leBar?
Last edited on
Nice riddle. You have to initialize both at once, so you can't do that in two separate lines:

std::pair<Foo, Bar> p(p.second, p.first);

demo: http://ideone.com/qTGtJ

It works in gcc, intel, clang, but I am not sure off-hand if it's only pushing the borders of legality or is actual UB.

In real-life, non-static references are rarely useful as class members, since they prohibit copy assignment.
Last edited on
closed account (10oTURfi)
Amazing!

As long as it works, nothing else matters :)
Matters to me.

It is guaranteed legal if you make those reference members public and use aggregate initialization, as follows:

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>
struct Bar;
struct Foo
{
    Bar& refBar;
    int n;
    void show() const;
};
 
struct Bar
{
    Foo& refFoo;
    int n;
    void show() const;
};
 
void Foo::show() const
{
    std::cout << "Foo.n is " << n
              << " Foo.refBar.n is " << refBar.n
              << '\n';
}
 
void Bar::show() const
{
     std::cout << "Bar.n is " << n
               << " Bar.refFoo.n is " << refFoo.n
               << '\n';
}
 
int main()
{
    struct {Foo f; Bar b;} s = {{s.b, 2}, {s.f, 1}};
    s.f.show();
    s.b.show();
}


demo: http://ideone.com/H0TsQ

With constructors, I am not sure, I'll check.
The reason you're finding this difficult to do is because it's very dangerous. You really shouldn't be doing it.

One of these objects will not be fully constructed at the time its reference is assigned, which leaves potential for a dangling references which can cause strange behavior / crashes. Furthermore I'm not sure if there's even a way to tell WHICH object is the one that won't be constructed.

This means neither Foo nor Bar's constructor (or the constructor of any derived classes) can use those references or call any functions that use the references. Since that is very difficult to enforce, you're basically BEGGING to shoot yourself in the foot with this.

Don't do it. Redisign your system so this isn't necessary.
Last edited on
Topic archived. No new replies allowed.