Доступ к защищенному члену параметра шаблона - PullRequest
0 голосов
/ 29 июля 2010

У меня есть класс шаблона, для которого мне нужен доступ к защищенной функции-члену параметра шаблона, например:

class Foo
{
protected:
    void foo() {}
};

template<typename T>
class Bar
{
public:
    static void bar(T& self){self.foo();}
};
...
Foo f;
Bar<Foo>::bar(f);

Моя проблема заключается в получении доступа к защищенному методу.Я попытался поместить friend class T в Bar, но это не разрешено в c ++ (edit: и в любом случае не решил бы мою проблему, так что это казалось).Я попытался позволить Bar наследовать от T (template<typename T> class Bar: public T (возможно, использовалось частное наследование, но открытый интерфейс Bar не очень важен, так как сам класс только внутренний)), но это не позволило получить доступ к foo() или.Итак, как мне получить доступ к методу foo()?

Edit: Foo не должен знать Bar<Foo>, так как существует довольно много Bar классов.Однако я могу внести другие изменения в Foo (конечно, не изменяя общедоступный интерфейс).

Ответы [ 4 ]

5 голосов
/ 29 июля 2010

ОК, это хак "гниль в аду".Вы можете злоупотреблять тем, что можете создавать указатели на члены, указывающие на защищенные базовые члены из производного класса.

class Foo
{
protected:
    void foo() {}
};

// Helper template to bypass protected access control
// for a member function called foo, taking no parameters
// and returning void.
template<typename T>
struct Unprotect : public T
{
    typedef void (T::*FooPtr)();
    static FooPtr GetFooPtr()
    {
        return &Unprotect::foo;
    }
};

template<typename T>
class Bar
{
public:
    static void bar(T& self){(self.*Unprotect<Foo>::GetFooPtr())();}
};

int main()
{
    Foo f;
    Bar<Foo>::bar(f);
}
2 голосов
/ 29 июля 2010

Вы сделали декларацию вашего друга в неверном направлении.Если Bar говорит, что Foo - это его друг, это означает, что Foo получает доступ к приватным данным Bar.Чтобы Bar получил доступ к личным данным Foo, Foo должен сказать, что Bar - его друг.

0 голосов
/ 21 декабря 2015

Если вы хотите получить доступ к защищенному члену производного класса из this, вы можете сделать это с ключевым словом using:

class A
{
protected:
  void i_am_protected () {}
};

template <class T>
class B : public T
{
  using T::i_am_protected;

  void call_me ()
  {
    i_am_protected(); // OK.
    this->i_am_protected(); // This compiles without the keyword.
  }
};

Если вам нужно B дляполучить доступ к защищенному члену A, когда объект передан B, вам нужно объявить B другом A:

class A
{
  template <class T>
  friend
  class B;

protected:
  void i_am_protected () {}
};

template <class T>
class B : public T
{
  void call_me (T& obj)
  {
    obj.i_am_protected(); // OK.
  }
};
0 голосов
/ 29 июля 2010
template<typename T>
class Bar
{
public:
    static void bar(T& self){self.foo();}
};

class Foo
{
protected:
    void foo() {}
    friend class Bar<Foo>;
};

void main()
{
    Foo f;
    Bar<Foo>::bar(f);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...