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

How to *not* deal with circular references in C++11.

// person.h – Buggy version (see Figure 1)
#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;
  string name_;
  typedef shared_ptr<person> spouse_ptr;
  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 spouse_; } 

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

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");

  // Here’s where the issue is produced. Both husband and wife get each other’s shared_ptr
  // targeting them
/* ---------------------------------- */
// 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