Почему функция друга будет определяться как часть структуры - Boost Thread_data?

StackOverflow https://stackoverflow.com/questions/3632349

  •  26-09-2019
  •  | 
  •  

Вопрос

Я пытаюсь понять какой-то код Boost, который вызывает PC-Lint Grov и использует ключевое слово «Друг», который я не думал, что был законным C ++, но компилирует OK в VS2008.

Я думал, что понял друг как способ объявить классы и функции. Я не думал, что было законно использовать на определении функции, как это. Однако, Страница MSDN очень специфичен:

Функции друга могут быть определены внутренние декларации класса. Эти функции находятся встроенные функции, и, как и встроенные функции члена, которые они ведут себя так, как будто они были определены сразу после того, как все члены класса были замечены, но до закрытия класса закрыты (конец декларации класса).

Функции друзей, определенные внутренние декларации класса, не рассматриваются в объеме обложенного класса; они в прилагаемости файлов.

Поэтому я понимаю, что это законно, если необычный синтаксис.

Я не уверен, что он получает их, потому что нормальная причина объявления чего-то друга - дать ему увеличенный доступ. Тем не менее, члены структуры все публичные по умолчанию, поэтому здесь нет никакой пользы здесь.

Я упускаю что-то глубокое или ли это просто какой-то стилистический жизненный вопрос, где кому-то не любит вставлять бесплатные функции после организма структуры?

Обратите внимание, что _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);
    }
...
};

Обновить

Благодаря ответу Чубыдада ниже, я думаю, что понимаю это сейчас, мое резюме о том, что происходит:

  • Они хотят, чтобы они ведут себя как бесплатные функции, так что вы можете просто компилировать intrusive_ptr_add_ref(somePtrToThreadData)
  • Если бы они были бесплатные функции, определенные после структуры, они будут видны в глобальном пространстве имен
  • Положить их в структуру с квалификатором подруги означает, что они находятся в пределах структуры, но не являются функциями элементов, поэтому ведут себя больше, как статические функции
  • Зависимый от аргумента означает, что они будут найдены при использовании, как если бы они были бесплатные функции
    • Сочетание вышеперечисленного означает, что они ведут себя как если бы они были виртуальными функциями, используя синтаксис бесплатных функций (принимая явный блок данных в качестве параметра, а не на него)
Это было полезно?

Решение

Это совершенно нормально, чтобы определить функции «друга» в определении класса. В этом конкретном случае, поскольку функция друга принимает параметр типа thread_data_base, Определение функции друга видно только в случае ADL (зависимый от аргументов) $ 3.4.2, когда они называются извнему лексикому объему определения класса

Проверить Пространство имен и принцип интерфейса от трав Sutter.

Другие советы

Я упускаю что-то глубокое или ли это просто какой-то стилистический жизненный вопрос, где кому-то не любит вставлять бесплатные функции после организма структуры?

Ваше предположение, кажется, является наиболее вероятной причиной: кто-то хотел объявить функцию вне класса, и все же сохранить декларацию в классе, потому что функция тесно связана с классом, поэтому они используют такое тайна синтаксиса. Почему они сделали это в первую очередь вместо того, чтобы сделать его функцией участника, это чья-то предположение.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top