2017-03-29 12 views
8

私は、これと同じような状況に遭遇するいくつかのコード、に取り組んでいます:Fooのコンストラクタ以外のいずれかへのアクセスを必要としないBarので、私は、ないFoofriendとしてBarを持っていることを好むだろうプライベートコンストラクタには、友人なしでアクセスできますか?

struct Bar; 

struct Foo{ 
    friend struct Bar; 
private: 
    Foo(){} 
    void f(){} 
    void g(){} 
}; 

struct Bar { 
    Foo* f; 
    Bar() { f = new Foo();} 
    ~Bar() { delete f;} 
}; 

int main(){ 
    Bar b; 
} 

Fooのプライベートメソッド(したがって、アクセスする必要はありません)。 BarさんにはFooさんを友達にしたことがないように許可する方法がありますか?

PS:質問が100%明確でない可能性があることを認識しました。友人かどうかにかかわらず、Barがすべて私的な方法にアクセスできるという事実(普通はfriendsの場合です)が、私が避けたいものです。幸いなことに、これまでに与えられた答えのどれも、その厄介な処方に問題はなかった。このクラスは、それが選択された関係者と共有して喜んだの秘密を仲介します弁護士を宣言し、コードで

struct Bar; 

struct Foo { 
    friend struct FooAttorney; 
private: 
    Foo(){} 
    void f(){} 
    void g(){} 
}; 

class FooAttorney { 
    static Foo* makeFoo() { return new Foo; } 
    friend struct Bar; 
}; 

struct Bar { 
    Foo* f; 
    Bar() { f = FooAttorney::makeFoo();} 
    ~Bar() { delete f;} 
}; 

int main(){ 
    Bar b; 
} 

は生命のファッションを模倣:

答えて

9

これはattorney-clientイディオムが何のためにあるのかを正確です。

+0

"No But But ..."というコメントを素敵な答えに変えてくれてありがとう。私はすでにコンストラクタのためにそれを使用できない理由があったことを恐れていた – user463035818

+0

@ tobi303恐怖を残して申し訳ありません。コメントしてから2秒後、私はあなたのコメントにコメントに答えようとしていることに気付きました。 – StoryTeller

5

別のクラスを導入したくない場合は、友情の輪を縮めてBarのコンストラクタFooの友達にできます。それはFooに利用できるようにするための定義、およびそれはまだBar与えます "Barを必要Fooのプライベート実装へのコンストラクタの無制限のアクセスを:

struct Foo; 

struct Bar { 
    Foo* f; 
    Bar(); 
    ~Bar(); 
}; 

struct Foo{ 
    friend Bar::Bar(); 
private: 
    Foo(){} 
    void f(){} 
    void g(){} 
}; 

Bar::Bar() : f(new Foo()) { 
} 

Bar::~Bar() { 
    delete f; 
} 

これは正確に何をしたい達成しないが、それは友情aを作りますより多くのターゲットを絞った。私に起こった

+0

私は何をしたいのですか?残念ながら、現在のところ 'Bar'は' Foo'の定義を知る必要がありますが、それは友情の問題を修正すれば一度変更される可能性があります。 – user463035818

+1

@ tobi303これはまさにあなたが望むものではありません。あなたが友人ができることを制限するように頼んだからです。 'Bar'のコンストラクタは、' Foo'との友好のために、まだ完全なアクセス範囲を保持しています。もちろん状況によってはこれは悪いことではないかもしれません。 – dasblinkenlight

+0

ああ、持っています。実際には友人なしで可能だったのかどうか気にしません。私は友達のコンセプトがまったく好きではありません(私はC++を意味します)。このアプローチでは、少なくとも私が愚かな何かをしないように気をつけなければならない範囲は、その最小限に限定されています – user463035818

3

一つの方法は、これだけBarは、それを作成することができますBarその友人を作る内部classを持っていたし、その内部classはこれだけclassの友人が呼び出すことができるFooコンストラクタへの追加パラメータとして使用することができますそれ。

class Foo 
{ 
public: 
    // only friends of the special key can invoke the constructor 
    // or any member function that includes it as a dummy parameter 
    class special_key {friend class Bar; special_key(){}}; 

    // making special_key a dummy parameter makes sure only friends of 
    // the special key can invoke the function 
    Foo(special_key) {} 
    void f(){} 
    void g(){} 
}; 

class Bar 
{ 
public: 
    // only Bar functions can create the special key 
    Bar() { f = std::make_unique<Foo>(Foo::special_key()); } 

private: 
    std::unique_ptr<Foo> f; 
}; 

ならびに特定の機能へのアクセスを制限するこの技術はまた、直接の友情にはないスマートポインタの使用make機能することができます。

+0

私の解決策はかなり難しいでしょうが、その方向に最初に考えていました – user463035818

+1

@ tobi303私はこの技術また、あなたが友情を指示するスマートポインタを使用することができます。 – Galik

関連する問題