Weak Pointers and Circular References in C++ 11: Listing 3

Weak_ptr is an exhaust vent for circular references.

// person.h – Correct version (see Figure 2)
#ifndef PERSON_H_
#define PERSON_H_

#include <memory>
#include <string>

using namespace std;

class person {
  friend void get_couple_married(shared_ptr<person>, shared_ptr<person>);
  person() = delete;
  person(const string);

  string get_name() const;
  shared_ptr<person> get_spouse() const;
  // nested class that models a smart pointer that could be strong or weak
  class spouse_ptr {
    shared_ptr<person> strong_;
    weak_ptr<person> weak_;
    spouse_ptr& set(const shared_ptr<person>);
    spouse_ptr(const shared_ptr<person>);

    spouse_ptr& operator=(const shared_ptr<person>);

    shared_ptr<person> get() const;
  string name_;
  spouse_ptr spouse_;

  void set_spouse(const shared_ptr<person>);

#endif /* PERSON_H_ */
/* ---------------------------------- */
// person.cpp
#include "person.h"
#include <iostream>
#include <stdexcept>

using namespace std;

person::person(const string name) : name_{name} {
  cout << name_ << " instance created." << endl;

person::~person() {
  cout << name_ << " instance to be disposed." << endl;

string person::get_name() const { return name_; }

shared_ptr<person> person::get_spouse() const { return this->spouse_.get(); } 

void person::set_spouse(const shared_ptr<person> sp) {
  this->spouse_ = sp;

person::spouse_ptr::spouse_ptr() : strong_{nullptr}, weak_{} {}
person::spouse_ptr::spouse_ptr(const shared_ptr<person> sp) : strong_{nullptr}, weak_{} {

person::spouse_ptr& person::spouse_ptr::operator=(const shared_ptr<person> sp) {
  return set(sp);

shared_ptr<person> person::spouse_ptr::get() const {
  if (strong_!=nullptr)
    return strong_;
    return weak_.lock();

person::spouse_ptr& person::spouse_ptr::set(const shared_ptr<person> sp) {
  // the strong or weak reference is used depending on 
  if (sp->get_spouse()==nullptr) {
    strong_ = sp;
  } else {
    strong_ = nullptr;
    weak_ = sp;

  return *this;

void get_couple_married(shared_ptr<person> husband, shared_ptr<person> wife) {
  // checks arguments aren’t null
  if ((husband==nullptr)||(wife==nullptr))
    throw invalid_argument("get_couple_married(husband, wife): can't get nullptr as couple member");

  // checks arguments aren’t the same instance
  if (husband.get()==wife.get())
    throw invalid_argument("get_couple_married(husband, wife): husband and wife can't be the same person");

  // the husband strongly points to his wife, while she weakly points back to him
  // (see function person::spouse_ptr::set)
/* ---------------------------------- */
// main.cpp
#include <iostream>
#include "person.h"

using namespace std;

void get_couple_married() {
  shared_ptr<person> husband = make_shared<person>("John"), wife = make_shared<person>("Pocahontas");
  get_couple_married(husband, wife);
  cout << husband->get_name() << "'s wife is " << husband->get_spouse()->get_name() << "." << endl;
  cout << wife->get_name() << "'s husband is " << wife->get_spouse()->get_name() << "." << endl;

int main() {
  return 0;

About the Author

Diego Dagum is a software architect and developer with more than 20 years of experience. He can be reached at [email protected]

comments powered by Disqus


  • Vendors Update Controls for .NET Core 3.1, Blazor

    This week saw two third-party vendors of dev tools -- UX and UI toolkits and controls -- release new offerings that include support for two of Microsoft's main open source frameworks, the cross-platform .NET Core 3.1 and Blazor, which allows for creating browser-based web applications with C# instead of JavaScript.

  • C++ Is Focus of New Visual Studio 2019 v16.7 Preview 2

    C++ development is a focus point of the new Visual Studio 2019 v16.7 Preview 2, featuring a slew of tweaks and improvements touching upon remote SSH connections, IntelliSense support and more.

  • Clustering Non-Numeric Data Using C#

    Clustering non-numeric -- or categorial -- data is surprisingly difficult, but it's explained here by resident data scientist Dr. James McCaffrey of Microsoft Research, who provides all the code you need for a complete system using an algorithm based on a metric called category utility (CU), a measure how much information you gain by clustering.

  • So What's Up with Microsoft's (and Everyone Else's) Love of Rust?

    Microsoft already stewards several popular programming languages -- C#, TypeScript, F# -- so what's up with its love of Rust, along with the rest of the world?

  • C# Steps Up Programming Language Popularity Ladder

    Microsoft's C# programming language climbed a year-over-year notch on the TIOBE Index, which measures popularity among developers.

.NET Insight

Sign up for our newsletter.

Terms and Privacy Policy consent

I agree to this site's Privacy Policy.

Upcoming Events