Cyclic References

Apr 8, 2012 at 10:06am
Hi all,

If I have the following case;

1
2
3
4
5
6
7
8
9
class A
{
    B* b;
}

class B
{
    A* a;
}


I have a circular situation, haven't I? Does it happen only for shared pointers?

The more importantly,the situation above doesn't make the main loop infinite? Afterall one creates another and another creates another and so on...Doesn't it crashes the program?

King Regards
Apr 8, 2012 at 10:28am
It's not infinite because you call the nested objects 1 by 1. There's not like "keep going till you reach the bottom of the reference". This is not Excel. The program doesn't look for a "number" to display, but rather simply calls the object you're pointer is pointing at. It could be 10 levels deeper, but it's your call. It won't go 10 levels deeper until you dereference 10 times.

You'll be stunned when you see how Multi-dimensional containers are done with templates by giving a parameter for the dimensionality. That's really circular!!! and that could really drive the compiler (since templates are compile-time stuff) crazy and get it to crash sometimes.
Apr 8, 2012 at 10:49am
I have a circular situation, haven't I?
Yes, but it may be legitimate. A manager class may have pointers to the managed class and the managed class may want to know who's managing it.

Does it happen only for shared pointers?
No.

The more importantly,the situation above doesn't make the main loop infinite?
No, the example I gave is legitimate.

Afterall one creates another and another creates another and so on...Doesn't it crashes the program?
I wouldn't think so, it all depends what you're doing. I think you're confusing classes and instances.

This post covers some stuff.
http://www.cplusplus.com/forum/general/62930/#msg340590
Apr 8, 2012 at 3:10pm
> Afterall one creates another and another creates another and so on...
> Doesn't it crashes the program?

Only one of them can be an 'owning' pointer; the classes have to be written accordingly. For example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
struct B ;

struct A
{
       A() ;

       A( const A& ) = delete ;
       A& operator=( const A& ) = delete ;

       std::unique_ptr<B> pb ; // pointer with unique ownership
       // ...
};

struct B
{
    B( A* p ) : pa(p) {}
    A* pa ; // non-owning pointer
    // ...
};
Apr 8, 2012 at 7:05pm
what if I instantiate A and B like;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
A::A
{
      ... = new B();
}

B::B
{
      ... = new A();
}

int main()
{
     A* a = new A();
}


This situation is not legitimate I suppose..

That's why I mentioned smart pointer stuff(shared pointers). In the code piece above, I used raw pointers of c++ and it definetely crashed.

But if we use smart pointers, the case would not be the same isn't it? I mean I can have cyclic references but can be handled by weak pointers?

And finally, designing a system like the code above is the first thing that I shouldn't do. What say you about this?

Thanks for your useful answers btw.
Last edited on Apr 8, 2012 at 7:28pm
Apr 8, 2012 at 8:20pm
This situation is not legitimate I suppose.
Why not?

I used raw pointers of c++ and it definetely crashed.
I don't know what you mean. Any chance of posting your code?
Apr 8, 2012 at 8:51pm
Why not?


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
37
38
class Bok;
class At
{
public:

	At();

	Bok* _b;
	//Bok b;
};

class Bok
{
public:

	Bok();

	At* _a;
};

At::At()
{
	_b = new Bok();
}

Bok::Bok()
{
	_a = new At();
}

int main(int argc, char *argv[])
{
	QCoreApplication a(argc, argv);

	At* at = new At();

	return a.exec();
}



Because it's crashing above. That's why i'm telling it's not legitimate:).

I actually want to know how to avoid circular reference issue if I have one like above?

Any chance of posting your code?


I didn't face it in my projects. It just occured to me and wanted to enlighten about it.
Apr 8, 2012 at 9:50pm
If every a needs a new b, and every b needs a new a, that's an obvious design flaw. You fix it by fixing the design.
Apr 8, 2012 at 11:36pm
By each constructor creating the other object, you have an infinitely recursive loop. That's clearly wrong. But objects referring to each other of itself isn't necessarily a problem.

Clearly you had something in mind. Can you explain your design? We ought to be able to sort this out.
Topic archived. No new replies allowed.