<commit_before>#include <memory>
#include <iostream>

struct Good : std::enable_shared_from_this<Good> {
  std::shared_ptr<Good> getptr() { return shared_from_this(); }
  ~Good() { std::cout << "Good::~Good() called\n"; }
};

struct Bad {
  std::shared_ptr<Bad> getptr() { return std::shared_ptr<Bad>(this); }
  ~Bad() { std::cout << "Bad::~Bad() called\n"; }
};

struct Foo : std::enable_shared_from_this<Foo> {
  virtual ~Foo() { std::cout << "Foo::~Foo() called\n"; }
  virtual std::shared_ptr<Foo> getPtr() {
    std::cout << "Foo::getPtr() called\n";
    return shared_from_this();
  }
};

struct Bar : public Foo {
  virtual ~Bar() { std::cout << "Bar::~Bar() called\n"; }
  virtual std::shared_ptr<Foo> getPtr() {
    std::cout << "Bar::getPtr() called\n";
    return shared_from_this();
  }
};

int main() {
  {  // Good: the two shared_ptr's share the same object
    std::shared_ptr<Good> gp1(new Good);
    std::shared_ptr<Good> gp2 = gp1->getptr();
    std::cout << "gp2.use_count() = " << gp2.use_count() << '\n';
  }

  {  // Bad, each shared_ptr thinks it's the only owner of the object
    std::shared_ptr<Bad> bp1(new Bad);
    std::shared_ptr<Bad> bp2 = bp1->getptr();
    std::cout << "bp2.use_count() = " << bp2.use_count() << '\n';
  }

  {
    std::shared_ptr<Foo> fooPtr = std::make_shared<Bar>();
    std::shared_ptr<Foo> foo2Ptr = fooPtr->getPtr();
    std::cout << "foo2Ptr.use_count() = " << foo2Ptr.use_count() << '\n';
  }
}  // UB: double-delete of Bad
<commit_msg>Shared_from_this: add Interface Class<commit_after>#include <memory>
#include <iostream>

struct Good : std::enable_shared_from_this<Good> {
  std::shared_ptr<Good> getptr() { return shared_from_this(); }
  ~Good() { std::cout << "Good::~Good() called\n"; }
};

struct Bad {
  std::shared_ptr<Bad> getptr() { return std::shared_ptr<Bad>(this); }
  ~Bad() { std::cout << "Bad::~Bad() called\n"; }
};

struct IFoo {
  virtual ~IFoo() { std::cout << "IFoo::~IFoo() called\n"; }
  virtual std::shared_ptr<IFoo> getPtr() = 0;
};

struct FooBase : std::enable_shared_from_this<FooBase>, IFoo {
  virtual ~FooBase() { std::cout << "FooBase::~FooBase() called\n"; }
  virtual std::shared_ptr<IFoo> getPtr() {
    std::cout << "FooBase::getPtr() called\n";
    return shared_from_this();
  }
};

struct FooDerived : public FooBase {
  virtual ~FooDerived() { std::cout << "FooDerived::~FooDerived() called\n"; }
  virtual std::shared_ptr<IFoo> getPtr() {
    std::cout << "FooDerived::getPtr() called\n";
    return shared_from_this();
  }
};

int main() {
  {  // Good: the two shared_ptr's share the same object
    std::shared_ptr<Good> gp1(new Good);
    std::shared_ptr<Good> gp2 = gp1->getptr();
    std::cout << "gp2.use_count() = " << gp2.use_count() << '\n';
  }

  {  // Bad, each shared_ptr thinks it's the only owner of the object
    std::shared_ptr<Bad> bp1(new Bad);
    std::shared_ptr<Bad> bp2 = bp1->getptr();
    std::cout << "bp2.use_count() = " << bp2.use_count() << '\n';
  } // Ultra Bad: double-delete of Bad

  {
    std::shared_ptr<IFoo> fooPtr = std::make_shared<FooDerived>();
    std::shared_ptr<IFoo> foo2Ptr = fooPtr->getPtr();
    std::cout << "foo2Ptr.use_count() = " << foo2Ptr.use_count() << '\n';
  }
}

{'fraction_non_alphanumeric': 0.2062015503875969, 'fraction_numerical': 0.008372093023255815, 'mean_word_length': 4.2200647249190935, 'pattern_counts': {'":': 0, '<': 98, '<?xml version=': 0, '>': 42, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4089188', 'n_tokens_mistral': 1250, 'n_tokens_neox': 1201, 'n_words': 242}