2011-06-15 78 views
0

我从Visual c得到warning C4355: 'this' : used in base member initializer list ++ 2010:封闭缺失者

我有一个类拿着手柄,我想自动关闭句柄即使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的东西,如_handle(nullptr, bind(PortDeleter, placeholders::_1, ref(_log)))关闭,但是这需要一个单独的定义。

我的问题:这个具体实例的警告是一个问题吗?无论哪种方式,详细原因是什么?有没有一种简单的方法来避免它?

+0

您的lambda是否必须捕获所有内容('[&]')?如果你只是做了'[]'(或'[&_log]')会发生什么? – 2011-06-15 05:45:34

+0

仍然是同样的问题,因为_log实际上是这个 - > _ log。 [&lg]虽然工作。 – 2011-06-15 19:21:22

+0

哦,当然 - 你不能在没有'this'的情况下访问'_log',但是你可以访问'lg'。抱歉! – 2011-06-15 19:34:11

回答

1

简而言之,如果您传递this指针,并且它用于访问初始化程序列表或析构函数Bad members Happen™中的成员函数或变量。如果您知道这种情况不会发生,请随时忽略警告。当然,这也是一个很好的警告 - 如果在析构函数中访问的任何函数或变量属于类,那么这是不安全的,因为您可能在构建之前/销毁之后访问它们。如果你知道你的初始化/销毁命令,这个问题并不重要,但通常是一个不好的举动,因为这使得维护工作变得非常烦琐。正如你可以捕获构造函数参数,我不得不建议。

+0

谢谢DeadMG,[&lg]工作。出于好奇,在这种情况下捕获的参数如何存储?它是否在与智能指针相关的内存中?看起来在Foo对象的生命周期中,会有两个lg副本。 – 2011-06-15 19:23:46

+0

我想这就好像你写了'struct Foo {int & a; Foo(int&a):a(a){}};',引用将被存储在函数对象的某个地方。最好不要在原始对象超出范围之后使用它! – 2011-06-15 19:38:57