a() というプライベート メソッドを持つクラス A があります。a() にアクセスする必要があるクラス B もあります (ただし、B だけが a() にアクセスできる必要があるため、a() はプライベートです)。フレンド指定子を使用できるようになりましたが、それにより、A の他のプライベート メソッド (b() および c() と呼びましょう) も B で使用できるようになり、その動作は望ましくありません。
A の a() だけを B にアクセス可能にする方法はありますか?
a() というプライベート メソッドを持つクラス A があります。a() にアクセスする必要があるクラス B もあります (ただし、B だけが a() にアクセスできる必要があるため、a() はプライベートです)。フレンド指定子を使用できるようになりましたが、それにより、A の他のプライベート メソッド (b() および c() と呼びましょう) も B で使用できるようになり、その動作は望ましくありません。
A の a() だけを B にアクセス可能にする方法はありますか?
方法があります-クラスにパブリックテンプレート関数がある場合:
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から盗んだことを告白しなければなりません...
いいえ、ありませんが、正確なクラスを指定すると、B だけが A のプライベート メンバーにアクセスできます。どのメソッドが呼び出されるかに注意する必要があります。
友人関係は継承されないので、B の可能なサブクラスについて心配する必要はありません。
これは、いくつかの「ひねり」で行うことができます。
メソッド 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'
}
};
それが役に立てば幸い !
はい、簡単な方法があります。次のように、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();