c++ - How to create a class setup where two classes each holds an instance of the other? - Stack Overflow

时间: 2025-01-06 admin 业界

I have a class setup like this, where each class holds a member of the other one:

class b;

class a
{
    b var;
};

class b
{
    a var;
};

How do I make it work?

I have a class setup like this, where each class holds a member of the other one:

class b;

class a
{
    b var;
};

class b
{
    a var;
};

How do I make it work?

Share Improve this question edited yesterday wohlstad 26.8k16 gold badges54 silver badges83 bronze badges asked yesterday SvyatSvyat 355 bronze badges 6
  • 2 You do infinite recursion... You need (smart) pointer to stop it. – Jarod42 Commented yesterday
  • @Jarod42 what do you mean? – Svyat Commented yesterday
  • At least one of the vars should be a [smart] pointer to a/b. – wohlstad Commented yesterday
  • 1 Why do you need this circular dependency? What problem is it supposed to solve? What is your design? Analysis? Requirements? Limitations? – Some programmer dude Commented yesterday
  • sizeof(a) is ∞, which is pretty big. Likewise, sizeof(b) is also ∞. To instantiate one of these objects, you may need a RAM upgrade. – Eljay Commented yesterday
 |  Show 1 more comment

2 Answers 2

Reset to default -1

This setup, as it's written, isn't possible - an instance of a contains an instance of b, which in turn contains an instance of a, which then contains an instance of b, ad infinitum.

Instead, you need the classes to hold pointers to each other:

class a {
   b* b;
};

class b {
   a* a;
};

At least one of your vars should be a [smart] pointer, to avoid an infinite inclusion (a holds b which holds a which holds b etc...).
This enables to use a forward declaration and break the inclusion cycle.

The decision if one is enough is dependant on the nature of your entities.

The relevant cases:

  1. If both entities are separate and should only be be referring to each other, both should use a pointer:

    class Entity1; // forward declaration
    
    class Entity2 {
        Entity1 * pEntity1;
    }
    
    class Entity2; // forward declaration (required if Entity1 is defined in a separate module)
    
    class Entity1 {
        Entity2 * pEntity2;
    };
    
  2. If one entity can be considered as a parent of the other (the child), the parent can (but is not required to) hold the child "by value" and the only the child should use a pointer:

    class Parent; // forward declaration
    
    class Child {
        Parent * pParent;
    };
    
    class Parent {
        Child child;
    };
    

Note that using 2 pointers is always a valid option, even in the case of parent/child.

A side note:
The pointers above might be replaced by smart pointers.
But this requires to address another issue of lifetime and ownership which I prefered to leave out of this answer to limit it to the scope of the question.

最新文章