简体   繁体   中英

C++ Circular Dependency Explanation

I have a basic example of a circular dependency using smart pointers. I've been looking for some explanations, and I know how to solve this problem, but I want to know what it is happening behind the scenes.

This is the code:

#include <iostream>
#include <memory>
using namespace std;

class Child;
class Parent {
  public:
    shared_ptr<Child> child;
    string name;
    Parent(string n) : name(n) {
      cout << "Parent: " << name << " constructor" << endl;
    }
    ~Parent() {
      cout << "Parent: " << name << " destructor" << endl;
    }
};

class Child {
  public:
    shared_ptr<Parent> parent;
    string name;
    Child(string n) : name(n) {
      cout << "Child: " << name << " constructor" << endl;
    }
    ~Child() {
      cout << "Child: " << name << " destructor" << endl;
    }
};

int main(int argc, char** argv) {
  shared_ptr<Parent> parent = make_shared<Parent>("Dad");//parent.use_count() => 1
  shared_ptr<Child> child = make_shared<Child>("Child");//child.use_count() => 1
  parent->child = child;//child.use_count() => 2
  child->parent = parent;//parent.use_count() => 2
  return 0;
}
//what happend at the end of the program?
//what happend when the shared_ptr destructors were called?
//was parent.use_count() decremented or is still 2?
//was child.use_count() decremented or is still 2?

Output:

Parent: Dad constructor
Child: Child constructor

What I want to know is the following

  • what happen when the shared_ptr destructors are called?
  • is parent.use_count() decremented or is still 2?
  • is child.use_count() decremented or is still 2?

I suppose the shared_ptr destructor code is something like:

~shared_ptr() {
  //I want to know what it is happening right here
  if (canDeletePointer(pointer)) {
    delete pointer;
  }
}

Thanks

  • When shared_ptr destructor is called, it decrements the link count, and if it becomes zero, it executes the destructor of the object and frees the memory.
  • After the main() function ends two shared pointers get removed, so their destructors are executed, decreasing the count from 2 to 1 for both son and dad.

Step by step

  1. Parent created and made shared in local variable parent . For ease of reading we'll call this allocation Parent. Parent count 1
  2. Child created and made shared in local variable child . For ease of reading we'll call this allocation Child. Child count 1
  3. parent updated to point at child . Child count 2
  4. child updated to point at parent . Parent count 2
  5. main ends
  6. child destroyed. Child count 1
  7. parent destroyed Parent count 1

Child and Parent are not destroyed because their respective counts never reach zero. The program exits and the OS reclaims all of the memory without their destructors being run. If this was a portion of a larger program, Child and Parent would go on taking up space in memory until program exit, unless some extreme lengths were taken to locate them, because their only external link was destroyed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM