我想了解一些引起PC-Lint悲傷的boost代碼,並以某種方式使用friend關鍵字,這種方式我並不認爲是合法的C++,但在VS2008中編譯好。爲什麼朋友函數會被定義爲struct - boost thread_data的一部分?
我以爲我理解朋友是一種聲明類和函數的方法。我不認爲用這種函數定義是合法的。但是,the MSDN page是非常具體的:
朋友函數可以在類聲明中定義。這些函數是內聯函數,並且像成員內聯函數一樣,它們的行爲就好像在所有類成員已經被查看之後但在類作用域關閉之前(類聲明結束)一樣。
在類聲明中定義的朋友函數不在封閉類的範圍內考慮;他們在文件範圍內。
所以我明白,這是合法的,如果不尋常的語法。
我不確定它是如何得到它們的,因爲聲明某個朋友的正常原因是爲了增加訪問權限。然而,一個結構的成員默認都是公共的,所以這裏沒有這樣的好處。
我是否缺少深奧的東西,或者這只是一些文體提升問題,有人不喜歡在結構的主體之後放置內聯自由函數?
請注意,_InterlockedIncrement是Win32上的內部函數。
# define BOOST_INTERLOCKED_INCREMENT _InterlockedIncrement
struct thread_data_base
{
long count;
detail::win32::handle_manager thread_handle;
detail::win32::handle_manager interruption_handle;
boost::detail::thread_exit_callback_node* thread_exit_callbacks;
boost::detail::tss_data_node* tss_data;
bool interruption_enabled;
unsigned id;
thread_data_base():
count(0),thread_handle(detail::win32::invalid_handle_value),
interruption_handle(create_anonymous_event(detail::win32::manual_reset_event,detail::win32::event_initially_reset)),
thread_exit_callbacks(0),tss_data(0),
interruption_enabled(true),
id(0)
{}
virtual ~thread_data_base()
{}
friend void intrusive_ptr_add_ref(thread_data_base * p)
{
BOOST_INTERLOCKED_INCREMENT(&p->count);
}
...
};
更新
得益於以下Chubsdad的答案,我想我明白,現在,我發生了什麼事的總結:
- 他們希望這些表現得像免費功能,讓你可以只編譯
intrusive_ptr_add_ref(somePtrToThreadData)
- 如果它們是在結構體後面定義的自由函數,它們將在全局命名空間中可見
- 把它們的結構內與朋友預選賽意味着它們的作用域的結構裏面,但不是成員函數,這樣的行爲更像靜態函數
- Argument-dependent Lookup意味着使用時就好像它們是免費的功能
-
他們會被發現
- 它們的行爲如同它們是使用自由函數的語法(考慮,而不是在其上調用的顯式數據塊作爲PARAM)
很坦率地說它看起來毫無意義,也許'friend'關鍵字強制函數以某種模糊的方式內聯? – 2010-09-03 01:16:27
何時在代碼中註釋時,您需要一個? :) – 2010-09-03 01:18:59
難道這是解決模板類的依賴類型問題的方法嗎? - 可能會查找朋友不在的位置,或許?順便說一句,AFAIK使這個朋友不太可能強迫這個內聯比成爲它的成員 - 但有理由使用「內聯」語法的朋友(例如看看巴頓 - 納克曼的伎倆 - http:// en.wikipedia.org/wiki/Barton-Nackman_trick)。 – Steve314 2010-09-03 01:40:13