Разрешить доступ класса для одного частного члена - PullRequest
3 голосов
/ 02 января 2012

У меня есть класс A, у которого есть закрытый метод, называемый a ().У меня также есть класс B, которому нужен доступ к a () (но только B должен иметь доступ к a (), поэтому a () является приватным).Теперь я мог бы использовать спецификатор друга, но это сделало бы другие частные методы A (давайте назовем их b () и c ()) также доступными для B, и я не хочу такого поведения.

Есть ли способсделать только () из A доступным для B?

Ответы [ 4 ]

4 голосов
/ 02 января 2012

Есть способ - если у вашего класса есть публичная функция шаблона:

class A {
    // apparently private
    void priv () { std::cout << "got you A::a()" << std::endl ; }
public:
    template <class T> 
    void abuse() {}
    };


struct Thief {};

template <>
void A::abuse<Thief>() {
    this->priv();
    }

int main() {
    A a;
    // obviously do not compile :   a.priv();
    // this i OK
    a.abuse<Thief>();

    return 0;
    }

Я должен признаться, что украл это у GotW ...

1 голос
/ 02 января 2012

Нет, нет, но, как вы укажете точный класс, только B может получить доступ к закрытым членам A. Вам просто нужно позаботиться о том, какой метод вызывается.

Поскольку дружеские отношения не наследуются, вам не нужно беспокоиться о возможных подклассах B.

0 голосов
/ 02 января 2012

Да, у меня есть простой способ.Пусть B имеет указатель на A :: a (), например:

typedef boost::function<void ()> functype;

class A {        
private:
    void a();
};

class B {
public:
    void setfp(functype f) {m_f = f;}
    void foo() {
        // do some stuff
        m_f();
    }
private:
    functype m_f;
};

A a;
B b;
b.setfp(boost::bind(&A::a, &a));
b.foo();
0 голосов
/ 02 января 2012

Это может быть сделано с некоторым «поворотом».

Просто выведите метод a () из класса A в родительский класс, в котором B является классом-другом, и пусть A наследует его.это оставит a () как метод в A, но единственный закрытый метод, доступный другу его родителя B.

, вот очень простой код для пояснения того, что я сказал:

class parent
{
    friend class B;
private:
    void a() {}
};

class A:public parent
{
private:
    void b() {}
    void c() {}
};


class B
{
    A* m_a;
public :
    B() 
    {
        m_a = new A();
        m_a->a(); // OK
        m_a->b(); //  error C2248: 'A::b' : cannot access private member declared in class 'A'

    }
};

надеюсь, это поможет!

...