初始化列表中的闭包删除器 (C++0x) 和编译器警告
我从 Visual C++ 2010 收到 警告 C4355: 'this' :used in base memberinitializer list
:
我有一个持有句柄的类,并且我想自动关闭该句柄,即使该类的 ctor 失败(因此不会调用其 dtor)。但是,我不想费心制作整个句柄包装类,而宁愿将其保存在智能指针中。所以我写了这样的:
foo.h
~~~~~
class Foo
{
...
Log &_log;
std::unique_ptr<void, std::function<void (void *)>> _handle;
...
}
foo.cpp
~~~~~~~
#include <windows.h>
Foo::Foo(Log &lg, ...) : _log(lg), ... _handle(nullptr, [&](void *h){ if (h) { if (!CloseHandle(h)) LOG(_log, "Could not close port: " << LastWinErr()); h = nullptr; } })
{
HANDLE h(CreateFile( ...
if (h == ...
_handle.reset(h);
... // Bunch of other stuff that could potentially throw
}
在闭包之前,我使用诸如 _handle(nullptr, bind(PortDeleter, placeholders::_1, ref(_log))) 之类的东西初始化 _handle,但这需要单独的定义。
我的问题:该警告是否与此特定实例有关?不管怎样,具体原因是什么?有没有一种简单的方法可以避免它?
I get a warning C4355: 'this' : used in base member initializer list
from Visual C++ 2010:
I have a class holding a handle, and I want to automatically close the handle even if the ctor for the class fails (so its dtor is not called). However, I don't want to bother making a whole handle-wrapping class, and would rather hold it in a smart pointer. And so I wrote this:
foo.h
~~~~~
class Foo
{
...
Log &_log;
std::unique_ptr<void, std::function<void (void *)>> _handle;
...
}
foo.cpp
~~~~~~~
#include <windows.h>
Foo::Foo(Log &lg, ...) : _log(lg), ... _handle(nullptr, [&](void *h){ if (h) { if (!CloseHandle(h)) LOG(_log, "Could not close port: " << LastWinErr()); h = nullptr; } })
{
HANDLE h(CreateFile( ...
if (h == ...
_handle.reset(h);
... // Bunch of other stuff that could potentially throw
}
Previously to the closure I was initializing _handle with something like _handle(nullptr, bind(PortDeleter, placeholders::_1, ref(_log)))
, but that requires a separate definition.
My questions: is the warning a concern for this specific instance? Either way, what is the detailed reason? Is there a trivial way to avoid it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
简而言之,如果您传递
this
指针,并且它用于访问初始值设定项列表或析构函数中的成员函数或变量,则会发生坏事™。如果您知道这种情况不会发生,请随意忽略该警告。当然,这也是一个很好的警告 - 如果您在析构函数中访问的任何函数或变量属于该类,那么这是不安全的,因为您可能在构造之前/销毁之后访问它们。如果您知道初始化/销毁命令,那么问题并不重要,但通常是一个糟糕的举动,因为这充其量会使维护变得相当繁琐。由于您可以捕获构造函数参数,因此我不得不推荐这样做。The short is, if you pass your
this
pointer around and it's used to access member functions or variables in the initializer list or in the destructor, Bad Things Happen™. If you know that isn't going to happen, then feel free to ignore the warning. Of course, it's also a good warning- if any of the functions or variables that you access in the destructor belong to the class, then this is unsafe, as you may be accessing them prior to their construction/after their destruction. The problem is not critical if you know your initialization/destruction orders, but generally a bad move as this makes maintenance rather fiddly at best. As you could capture the constructor parameter instead, I'd have to recommend that.