shared_from_this

shared_from_this是基类enable_shared_shared_from_this的一个方法,允许继承类获取一个只想自身的shared_ptr智能指针,这个智能指针与已有的shared_ptr共享所有权。

我们可以查看其源码

/*VS2019*/
template <class _Ty>
class enable_shared_from_this { // provide member functions that create shared_ptr to this
public:
    using _Esft_type = enable_shared_from_this;

    _NODISCARD shared_ptr<_Ty> shared_from_this() {
        return shared_ptr<_Ty>(_Wptr);
    }

    _NODISCARD shared_ptr<const _Ty> shared_from_this() const {
        return shared_ptr<const _Ty>(_Wptr);
    }

    _NODISCARD weak_ptr<_Ty> weak_from_this() noexcept {
        return _Wptr;
    }

    _NODISCARD weak_ptr<const _Ty> weak_from_this() const noexcept {
        return _Wptr;
    }

protected:
    constexpr enable_shared_from_this() noexcept : _Wptr() {}

    enable_shared_from_this(const enable_shared_from_this&) noexcept : _Wptr() {
        // construct (must value-initialize _Wptr)
    }

    enable_shared_from_this& operator=(const enable_shared_from_this&) noexcept { // assign (must not change _Wptr)
        return *this;
    }

    ~enable_shared_from_this() = default;

private:
#if _HAS_IF_CONSTEXPR
    template <class _Yty>
    friend class shared_ptr;
#else // ^^^ _HAS_IF_CONSTEXPR // !_HAS_IF_CONSTEXPR vvv
    template <class _Other, class _Yty>
    friend void _Enable_shared_from_this1(const shared_ptr<_Other>& _This, _Yty* _Ptr, true_type) noexcept;
#endif // _HAS_IF_CONSTEXPR

    mutable weak_ptr<_Ty> _Wptr;
};

具体的使用方法如下

#include<memory>
#include<iostream>

class A : public std::enable_shared_from_this<A>{
	public:
		A(){
			std::cout << "construc A" << std::endl;
		}
		~A(){
			std::cout << "deConstruct A" << std::endl;
		}
		void fun(){
			std::shared_ptr<A> p = shared_from_this();
		}
};

int main(){
	std::shared_ptr<A> foo, bar;
	foo = std::make_shared<A>();
	foo->fun();
	bar = foo->shared_from_this();
	if(!foo.owner_before(bar) && !bar.owner_before(foo)){
		std::cout << "foo and bar share ownership" << std::endl;
	}
}

/* out
construc A
foo and bar share ownership
deConstruct A
*/

会产生两种错误,一种是产生bad_weak_ptr错误,这类错误编译时正常,运行时报错:

会产生这种错误有两种原因:

1、在派生类的构造函数中调用shared_from_this函数

class B : public std::enable_shared_from_this<B>{
	public:
		B(){
			std::cout << "construc B" << std::endl;
            std::shared_ptr p = shared_from_this();
		}
		~B(){
			std::cout << "deConstruct B" << std::endl;
		}
};

由于B本身都没有构造完成,此时相当于使用this指针自然就会报错,此时enable_shared_from_this中的weak_ptr还未完成初始化。

2、利用一个裸指针,指向堆(栈)上的对象,没有使用shared_ptr的构造方式,造成enable_shared_from_this中的weak_ptr没有初始化

class C : public std::enable_shared_from_this<C>{
	public:
		C(){
			std::cout << "construc C" << std::endl;
		}
		~C(){
			std::cout << "deConstruct C" << std::endl;
		}
        void fun(){
            std::shared_ptr<C> p = shared_from_this();
}
};

int main(){
    C* c = new C();//C* c;
    c->fun();
}

第二种错误是继承导致,即在同一个继承体系下只能出现一个enable_shared_from_this父类,在父类已经继承了enable_shared_from_this时,子类需要继续无法继续使用enable_shared_from_this方法,子类只能对父类的shared_from_this的返回值进行类型转换。

#include<memory>
#include<iostream>
class A : public std::enable_shared_from_this<A>{
	public:
		A(){
			std::cout << "construc A" << std::endl;
		}
		virtual ~A(){
			std::cout << "deConstruct A" << std::endl;
		}
        void fun1(){
            auto p = shared_from_this();
}
};


class B : public A{
	public:
		B(){
			std::cout << "construc D" << std::endl;
		}
		~B(){
			std::cout << "deConstruct D" << std::endl;
		}
        void fun(){
            auto p = std::dynamic_pointer_cast<B>(shared_from_this());
}
};

int main(){
	std::shared_ptr<B> b = std::make_shared<B>();
	b->fun();
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值