Skip to content

Latest commit

 

History

History
124 lines (90 loc) · 2.91 KB

smart_pointers_weak_ptr.md

File metadata and controls

124 lines (90 loc) · 2.91 KB

Cyclic dependencies

cyclic dependencies

  • Cyclic dependency is where you have class A with self-referencing member.
  • Cyclic dependency is where you have two classes A and B where A has a reference to B which has a reference to A.

Cyclic dependencies

a kid stroking a dog, stroking a kid, stroking a dog...

  • Cyclic dependency is where you have class A with self-referencing member.
  • Cyclic dependency is where you have two classes A and B where A has a reference to B which has a reference to A.
  • How to fix it?

std::weak_ptr<> to the rescue

Traits

  • does not own an object
  • observes only
  • must be converted to std::shared_ptr<> to access the object
  • can be created only from a std::shared_ptr<>
weak pointers

std::weak_ptr<> usage

#include <memory>
#include <iostream>

struct Msg { int value; };

void checkMe(const std::weak_ptr<Msg> & wp) {
    std::shared_ptr<Msg> p = wp.lock();
    if (p)
        std::cout << p->value << '\n';
    else
        std::cout << "Expired\n";
}

int main() {
    auto sp = std::shared_ptr<Msg>{new Msg{10}};
    auto wp = std::weak_ptr<Msg>{sp};
    checkMe(wp);
    sp.reset();
    checkMe(wp);
}
> ./a.out
10
Expired

std::shared_ptr<> cyclic dependencies

  • How to solve this problem?
#include <memory>

struct Node {
    std::shared_ptr<Node> child;
    std::shared_ptr<Node> parent;
};

int main () {
    auto root = std::shared_ptr<Node>(new Node);
    auto child = std::shared_ptr<Node>(new Node);
    root->child = child;
    child->parent = root;
}

Breaking cycle - solution

  • Use std::weak_ptr<Node> in one direction
#include <memory>
struct Node {
    std::shared_ptr<Node> child;
    std::weak_ptr<Node> parent;
};

int main () {
    auto root = std::shared_ptr<Node>(new Node);
    auto child = std::shared_ptr<Node>(new Node);
    root->child = child;
    child->parent = root;
}
==148== All heap blocks were freed -- no leaks are possible