关于enable_shared_from_this的使用疑问

stecdeng 2017-10-26 12:50:29
今天遇到一段代码 使用方式比较不常见 个人不太理解
而且自以为可能有使用错误的可能 向各位请教
代码如下

template<class T>
class Socket : public std::enable_shared_from_this<T>
/*
这种使用enable_shared_from_this的方式正确么???
class Socket : public std::enable_shared_from_this<Socket> //T另外处理
*/
{
//.....
private:
tcp::socket _socket; //boost
MessageBuffer _readBuffer; // other class
public:
void ReadHandlerInternal(boost::system::error_code error, size_t transferredBytes)
{
if (error)
{
CloseSocket();
return;
}

_readBuffer.WriteCompleted(transferredBytes);
ReadHandler();
}
void AsyncReadWithCallback(void (T::*callback)(boost::system::error_code, std::size_t))
{
if (!IsOpen())
return;

_readBuffer.Normalize();
_readBuffer.EnsureFreeSpace();
_socket.async_read_some(boost::asio::buffer(_readBuffer.GetWritePointer(), _readBuffer.GetRemainingSpace()),
std::bind(callback, this->shared_from_this(), std::placeholders::_1, std::placeholders::_2));
/*
这里能够理解 传入的是T的成员函数 所以指针也是shared_from_this
*/
}
void AsyncRead()
{
if (!IsOpen())
return;

_readBuffer.Normalize();
_readBuffer.EnsureFreeSpace();
_socket.async_read_some(boost::asio::buffer(_readBuffer.GetWritePointer(), _readBuffer.GetRemainingSpace()),
std::bind(&Socket<T>::ReadHandlerInternal, this->shared_from_this(), std::placeholders::_1, std::placeholders::_2));
/*
这里为什么不是传入Socket的指针
*/
}

};
...全文
953 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
Hit_HSW 2020-11-21
  • 打赏
  • 举报
回复
我认为在你的这个代码里面的位置使用this->shared_from_this()没有问题,是因为你在其他地方,必须在这个代码的前面,实际上就定义了一个共享指针,此时,你用this->shared_from_this()或shared_from_this()都不会报错,否则,你怎么使用都是错的
FancyMouse 2017-10-28
  • 打赏
  • 举报
回复
引用 12 楼 xsklld 的回复:
[quote=引用 4 楼 FancyMouse 的回复:] 上enable_shared_from_this<T>是为了让async_read的函数对象借助shared_ptr<T>保存这个Socket的生存期。把继承类用基类shared_ptr在基类析构函数是虚函数的时候才可以做。所以你这里如果T有虚析构的话这代码勉强没问题。
这样不需要Socket继承T吗?[/quote] 需要。但是他能调用shared_from_this()说明this能隐式转成T*,如果没有继承关系的话直接就一票编译错误了。lz的语气看上去像是问如何理解能跑的代码,而不是说代码有错,所以我也就没特别强调这点。
stecdeng 2017-10-28
  • 打赏
  • 举报
回复
引用 13 楼 FancyMouse 的回复:
[quote=引用 12 楼 xsklld 的回复:] [quote=引用 4 楼 FancyMouse 的回复:] 上enable_shared_from_this<T>是为了让async_read的函数对象借助shared_ptr<T>保存这个Socket的生存期。把继承类用基类shared_ptr在基类析构函数是虚函数的时候才可以做。所以你这里如果T有虚析构的话这代码勉强没问题。
这样不需要Socket继承T吗?[/quote] 需要。但是他能调用shared_from_this()说明this能隐式转成T*,如果没有继承关系的话直接就一票编译错误了。lz的语气看上去像是问如何理解能跑的代码,而不是说代码有错,所以我也就没特别强调这点。[/quote] 但是这点恰恰是理解的重点 这说明这种不太一般的写法 还是有很多限制 我是我疑惑的来源 谢谢
stecdeng 2017-10-27
  • 打赏
  • 举报
回复
引用 8 楼 sdghchj 的回复:
详情去了解一下std::shared_ptr<T> 智能指针的用法,用了它后,就尽量不要用该T对象的裸指针,因为生命周期的问题,除非你自己能严格把控该对象的生命周期,否则就最好用std::shared_ptr<T> ,为了解决该对象类成员方法内部要将自身指针传出的问题,才有了继承std::enable_shared_from_this<T>的用法,在方法内使用shared_from_this()
你好 那么请问 1 template<class T> class Socket : public std::enable_shared_from_this<T> 这个是针对T的自身指针还是Socket的自身指针的使用? 2 在bing 函数中 std::bind(callback, this->shared_from_this() std::bind(&Socket<T>::ReadHandlerInternal, this->shared_from_this() 一个是T的成员函数 一个是Socket的成员函数 为什么都传入this->shared_from_this()? 而且传入的都是this->shared_from_this()? 这个根据shared_ptr手头的资料 我还不能理解
sdghchj 2017-10-27
  • 打赏
  • 举报
回复
详情去了解一下std::shared_ptr<T> 智能指针的用法,用了它后,就尽量不要用该T对象的裸指针,因为生命周期的问题,除非你自己能严格把控该对象的生命周期,否则就最好用std::shared_ptr<T> ,为了解决该对象类成员方法内部要将自身指针传出的问题,才有了继承std::enable_shared_from_this<T>的用法,在方法内使用shared_from_this()
FancyMouse 2017-10-27
  • 打赏
  • 举报
回复
引用 5 楼 stecdeng 的回复:
而且不用shared_from_this而是this->shared_from_this()的形式 感觉很怪异
加this->只是因为dependent name的原因,因为是从模板类继承,不用this->的话编译器不从模板基类里获取这个名字,会unresolved symbol的。这个和shared_ptr的问题是没关系的。
xskxzr 2017-10-27
  • 打赏
  • 举报
回复
引用 4 楼 FancyMouse 的回复:
上enable_shared_from_this<T>是为了让async_read的函数对象借助shared_ptr<T>保存这个Socket的生存期。把继承类用基类shared_ptr在基类析构函数是虚函数的时候才可以做。所以你这里如果T有虚析构的话这代码勉强没问题。
这样不需要Socket继承T吗?
FancyMouse 2017-10-27
  • 打赏
  • 举报
回复
都讲了dependent name的问题和shared_ptr没关系

template<typename T>
struct A
{
	void foo(){}
};
template<typename T>
struct B : public A<T>
{
	void a()
	{
		this->foo(); //OK
		//foo();  编译错误
	}
};
stecdeng 2017-10-27
  • 打赏
  • 举报
回复
周末快乐 这个若没人回复 周一结贴
stecdeng 2017-10-26
  • 打赏
  • 举报
回复
引用 4 楼 FancyMouse 的回复:
上enable_shared_from_this<T>是为了让async_read的函数对象借助shared_ptr<T>保存这个Socket的生存期。把继承类用基类shared_ptr在基类析构函数是虚函数的时候才可以做。所以你这里如果T有虚析构的话这代码勉强没问题。
谢谢解答 还是不太了解 std::bind中 T的callback 和 Socket<T> 的函数 都是传递同样的值shared_from_this。我的理解应该是一个是 this->shared_from_this() 一个是shared_from_this()之类的写法 而且不用shared_from_this而是this->shared_from_this()的形式 感觉很怪异
FancyMouse 2017-10-26
  • 打赏
  • 举报
回复
上enable_shared_from_this<T>是为了让async_read的函数对象借助shared_ptr<T>保存这个Socket的生存期。把继承类用基类shared_ptr在基类析构函数是虚函数的时候才可以做。所以你这里如果T有虚析构的话这代码勉强没问题。
xskxzr 2017-10-26
  • 打赏
  • 举报
回复
class Socket : public std::enable_shared_from_this<Socket<T>>
stecdeng 2017-10-26
  • 打赏
  • 举报
回复
望回复 谢谢
stecdeng 2017-10-26
  • 打赏
  • 举报
回复
中午求教 大家解答下 谢谢

3,881

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 其它技术问题
社区管理员
  • 其它技术问题社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧