I am trying to understand some enhancement code that causes PC-Lint sorrow and uses the friend keyword in such a way that I did not think it was legal C ++, but it compiles OK in VS2008.
I thought I understood a friend as a way to declare classes and functions. I did not think it was legal to use this function definition. However, the MSDN page is very specific:
Friend functions can be defined inside class declarations. These functions are built-in functions and similar to the built-in functions of members, they behave as if they were defined immediately after all members of the class were noticed, but before the class area was closed (end of class declaration).
Friend functions defined within class declarations are not considered to be within the scope of the enclosing class; they are in the file area.
So, I understand that this is legal, if unusual syntax.
I'm not sure what he is getting, because the normal reason for declaring something as a friend is to increase his access. However, structure members are publicly accessible by default, so there is no such benefit.
Am I missing something deep or is it just some kind of stylistic raise problem when someone doesn't like to introduce built-in free functions after the body of the structure?
Note that _InterlockedIncrement is a built-in function on 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);
}
...
};
Update
Thanks to Chubsdad for the answer below, I think I understand it now, my summary of what is going on:
- , ,
intrusive_ptr_add_ref(somePtrToThreadData) - , ,
- , , -, .
- - , ,