Сама подружка - PullRequest
       16

Сама подружка

3 голосов
/ 31 декабря 2011

РЕДАКТИРОВАТЬ: Похоже, я полностью дезинформирован.Пожалуйста, закройте эту тему.Гах.

Для записи, следующие компилируются и работают:

class ForeverAlone
{
private:
  int m_friends;
  HANDLE m_handle;

public:
  ForeverAlone()
  {
    m_handle = CreateThread(NULL, 0, &ForeverAlone::SadThread, reinterpret_cast<void*>(this), 0, NULL);
  }

  ~ForeverAlone()
  {
    if (m_handle != NULL)
      CloseHandle(m_handle);
  }

protected:
  static unsigned long WINAPI SadThread(void* param)
  {
    ForeverAlone* thisObject = reinterpret_cast<ForeverAlone*>(param);

    // is there any way for me to access:
    thisObject->m_friends;
  }
};

Оригинальный вопрос: у меня есть метод статической защищенной нити, которому я передаю объект.Могу ли я каким-то образом создать класс friend, чтобы получить доступ к его закрытым членам?

Ответы [ 2 ]

11 голосов
/ 31 декабря 2011

Все методы класса, статические или нет, автоматически становятся «друзьями» класса.Friend используется для разрешения доступа к классу внешним функциям и классам.Класс всегда является своим собственным "другом".

1 голос
/ 31 декабря 2011

Сделайте это:

extern "c"  DWORD  __stdcall CInterfaceSadThread(LPVOID lpThreadParameter);

class ForeverAlone
{
  private:
    int m_friends;
    HANDLE m_handle;

  public:
    ForeverAlone()
    {
      m_handle = CreateThread(NULL, 0, 
                              &CInterfaceSadThread,
                              //
             // You may get arguments about using static_cast here
             // I still prefer reinterpret_cast as it makes it stick out
             // Thus I check it more carefully when I see it.
             // For this situation it works correctly
             // As casting to void* and back to the original are guaranteed.
                              reinterpret_cast<void*>(this), 
                              0, NULL);
    }

    ~ForeverAlone()
    {
      if (m_handle != NULL)
        CloseHandle(m_handle)
    }

  protected:
    friend DWORD  CInterfaceSadThread(LPVOID lpThreadParameter);
    DWORD WINAPI SadThread()
    {
      // Do Stuff here
      // Note: Just because you get here does not mean that the object is finished
      //       initializing. The parent thread may have been suspended after this
      //       one was created. Thus checking the state of member variables at this
      //       point is dangerous unless you can guarantee that construction has finished

      return result;
    }
};

Тогда в обратном вызове просто получите доступ к вашей функции;

extern "c" DWORD __stdcall  CInterfaceSadThread(LPVOID lpThreadParameter)
{
    // Note: You can only cast back to ForeverAlone* so be carefull
    //       Hence I use reinterpret_cast as this forces me to double check.
    ForeverAlone*  alone = reinterpret_cast<ForeverAlone*>(lpThreadParameter);
    return alone->SadThread();
}
...