2011-06-15 30 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