代码之家  ›  专栏  ›  技术社区  ›  Grizzly

访问模板参数的受保护成员

  •  0
  • Grizzly  · 技术社区  · 14 年前

    我有一个模板类,需要访问模板参数的受保护成员函数,如下所示:

    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 但这在c++中似乎是不允许的(编辑:无论如何也不能解决我的问题,所以看起来是这样)。我试着让Bar继承T( template<typename T> class Bar: public T foo() 方法?

    编辑: Foo Bar<Foo> ,因为有很多 Bar 班级。不过,我可以对Foo进行其他更改(当然不需要更改公共接口)。

    4 回复  |  直到 14 年前
        1
  •  5
  •   CB Bailey    14 年前

    好吧,这是一个“烂在地狱”的黑客。可以形成指向指向派生类中受保护基成员的成员的指针。

    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
  •  2
  •   Jerry Coffin    14 年前

    你做朋友宣言的方向不对。如果 Bar Foo 酒吧 的私人数据。为了 酒吧 获取 的私人数据, 不得不说 酒吧

        3
  •  0
  •   Mircea Ispas    14 年前
    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);
    }
    
        4
  •  0
  •   Yumiko    9 年前

    如果要访问受保护的成员,请使用派生类 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.
      }
    };
    

    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.
      }
    };