#include <memory>
#include <iostream>
 
struct Good: std::enable_shared_from_this<Good> // 注意:继承
{
    std::shared_ptr<Good> getptr() {
        return shared_from_this();//继承了一个方法,用弱针实现
    }//从此共享,代表这是已生成的共享,在总计数里面不应该+1,否则引用计数不对.用弱针(未加0)实现.
};
 
struct Bad
{
    // 错误写法:用不安全的表达式试图获得 this 的 shared_ptr 对象
    std::shared_ptr<Bad> getptr() {
        return std::shared_ptr<Bad>(this);//这个是应返回计数不变的共享针,如果为普通共享针的话,则析构出问题,因为已是共享针,+1会出错.这里应该是保持不变的共享针,即返回共享针,但计数未变化.
    }
    ~Bad() { std::cout << "Bad::~Bad() called\n"; }
};
 
int main()
{
    // 正确的示例:两个 shared_ptr 对象将会共享同一对象
    std::shared_ptr<Good> gp1 = std::make_shared<Good>();//1个共享针
    std::shared_ptr<Good> gp2 = gp1->getptr();//还是这1个共享针,gp2与gp1是完全相同的.这个共享针是假的共享针.未加引用计数的.如果等号右边是上一行这样的,才是真正的共享针.这里的gp2不过是相当于复制了一份gp1罢了.一个重复利用的假的共享针.
    std::cout << "gp2.use_count() = " << gp2.use_count() << '\n';//打印出来的是有几个共享针指向本地对象.这只是表面的肤浅的共享针个数(可指向不同对象/相同对象针),在共享针内部,一定有一个统计真正的共享针个数,即指向不同对象针的个数.
    //use_count指的是指向->当前共享针对象的共享针个数.
 
    // 错误的使用示例:调用 shared_from_this 但其没有被 std::shared_ptr 占有
    try {
        Good not_so_good;//不能这样构造.从此共享,开始必须是共享针,从此共享未+1.
        std::shared_ptr<Good> gp1 = not_so_good.getptr();//先不是共享针,这样获得的是未加引用计数的共享针,所以是错的.
    } catch(std::bad_weak_ptr& e) {//用弱针实现的未加0共享针.
        // C++17 前为未定义行为; C++17 起抛出 std::bad_weak_ptr 异常
        std::cout << e.what() << '\n';    
    }
 
    // 错误的示例,每个 shared_ptr 都认为自己是对象仅有的所有者
    std::shared_ptr<Bad> bp1 = std::make_shared<Bad>();//1个共享针
    std::shared_ptr<Bad> bp2 = bp1->getptr();//2个共享针,然而实际上只有1个对象.
    std::cout << "bp2.use_count() = " << bp2.use_count() << '\n';
} // UB : Bad 对象将会被删除两次

可能的输出:

gp2.use_count() = 2
bad_weak_ptr
bp2.use_count() = 1
Bad::~Bad() called
Bad::~Bad() called
*** glibc detected *** ./test: double free or corruption