Функция Friend обращается к закрытым членам класса, определенным в статической библиотеке - PullRequest
1 голос
/ 28 марта 2012

У меня есть статическая библиотека, написанная на C ++. У меня также есть заголовочные файлы для классов, определенных в статической библиотеке.

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

Ответы [ 2 ]

1 голос
/ 28 марта 2012

Технически неопределенное поведение использовать другую последовательность токенов для определения одного и того же объекта (здесь класса) в разных единицах перевода.

Какой бы техникой вы ни пользовались, пока она меняет последовательность токенов, составляющих ее, она является злом со стандартной точки зрения (хотя, вероятно, сработает на практике).

Йоханнес открыл способ сделать это, соблюдая Стандарт. Он основан на том факте, что, хотя a является частным атрибутом в классе A, &A::a может быть записан в контекстах, которые не могут записать A.a (возможно, упущение в Стандарте?).

Основной метод:

template<typename Tag, typename Tag::type M>
struct Rob { 
  friend typename Tag::type get(Tag) {
    return M;
  }
};

// use
struct A {
  A(int a):a(a) { }
private:
  int a;
};

// tag used to access A::a
struct A_f { 
  typedef int A::*type;
  friend type get(A_f);
};

template struct Rob<A_f, &A::a>;

int main() {
  A a(42);
  std::cout << "proof: " << a.*get(A_f()) << std::endl;
}

Расширение для простоты:

template<typename Tag, typename Member>
struct TagBase {
  typedef Member type;
  friend type get(Tag);
};

struct A_f : TagBase<A_f, int A::*> { };

EDIT

Этот трюк (забавно) явно разрешен Стандартом

§14.7.2 / 12 Обычные правила проверки доступа не применяются к именам, используемым для указания явных экземпляров. [...]

1 голос
/ 28 марта 2012

Вы имеете в виду, что хотите изменить заголовки, которые поставляются с библиотекой? Ни в коем случае не гарантируется, что добавление объявлений friend будет работать. Вы можете испортить связующую часть, даже если ваш компилятор говорит, что все в порядке.

Кроме того, если эти участники private, вы просто не получите к ним доступ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...