2011-10-28 15 views
1

対応するfriendバージョンのmethodsのコードを再利用することは可能ですか?例えば、以下の例では、doSomethinginitDoSomethingの両方の方法が同じ計算を行うため、それらの実装は実質的に同じです。そのようなことをコードを再利用するための最良の方法はどれでしょうか?コードを再利用する:友人以外の方法を使った友人の方法

template < typename T > 
class CFoo; 

template < typename T > CFoo<T> doSomething(double); 

template < typename T > 
class CFoo{ 
    public: 
     ... 
     friend CFoo<T> doSomething< >(double); 
     CFoo<T> initDoSomething(double); 
}; 

任意の提案は、私が達成したい何;-)

を歓迎しているようなものです。また、必ずしもオブジェクトを初期化する必要の有無にかかわらず myFooObject1 = doSomething(3.0);myFooObject1.doSomething(3.0);

+1

あなたは両方のバージョンが必要ですか?代わりにinitDoSomethingを静的関数にする必要はありませんか? – crazyjul

+0

initDoSomething()はCFooのメンバーにアクセスしますか?はいの場合、doSomething()と同じことをどうすればできますか?そうでない場合、それはなぜメンバーですか? –

+0

私の謙虚な意見では、友達やテンプレートは避けるべきです。必要な場合にのみそれらを使用し、論理的な意味を持ちます。なぜ、まさにあなたは達成しようとしていますか? –

答えて

0

達成する方法C++でのコード再利用は、共通コードを(おそらくパラメータ化された)共有関数に単純に因数分解することです。

あなたの場合、私はinitDoSomethingがプライベートメンバーにアクセスすることを前提としています(そうでなければ、それはなぜメンバー関数ですか?)。したがって、あなたの場合、共有関数は2つの引数をとり、initDoSomethingはそれをプライベートメンバーを共有関数の引数として渡します。

+0

あなたの答えをイラストにしてもよろしいですか?オリジナルの投稿を更新して、私が達成したいことを示しました。 – Javier

+0

"私はinitDoSomethingがプライベートメンバーにアクセスすることを前提としています(そうでなければ、なぜメンバー関数ですか?)。著者はそれが明らかにここに属していると思うからです。 – curiousguy

+0

@curiousguy:そうだけど、なぜ*著者はそれがそこに属していると思いますか?可能であれば、必要に応じて機能メンバーを作成する必要があります。 –

1

一般に、関数がクラスのプライベートデータメンバにアクセスする必要がある場合、それをフレンド関数ではなくクラスのメソッドにする必要があります。あなたのオブジェクトとストリームのような他の標準的なC++インタフェースとの間の共通インタフェースを作成するために、operator>>などのような友人機能を持つことが必要な場合があります。スタンドアロンフレンド機能の別の一般的な使用方法は、何らかの方法でパラメータ化される単一のファンクションインタフェースを作成することですが、そのファンクションのインタフェースを同じにしたい(つまり、単一のテンプレート関数が複数の異なるインスタンス化されたバージョンと同じ方法でその関数を呼び出す必要があります)。ただし、クラスのプライベートデータメンバーにアクセスできるように、クラスのフレンドとして機能を作成すると、プライベートデータメンバーのためにクラスが作成するデータカプセル化のアイデアが損なわれます。

あなたの場合、doSomethingは、今では機能の宣言とともに、理由がないように思われる理由は明白に説明されていません公開メソッドのCFooにすることはできません。第2に、doSomething関数のグローバルステートを初期化しようとしている場合は、initDoSomethingをメソッドではなくクラスの静的関数にして、CFoo<T>のすべてのバージョンをdoSomethingCFoo<T>という単一インスタンスです。現時点では、doSomethingで使用する前に、すべてのインスタンスをCFoo<T>に初期化する必要があります。意味的に意味がないのはdoSomethinginitDoSomethingと呼び出す前にCFoo<T>インスタンスを作成して、doSomethingの呼び出しのためにそのインスタンスを初期化することができるからです。

+0

オリジナルの投稿を更新して、何を達成したいのかを示しました。 – Javier

+0

基本的に工場の機能がほしいと思うように聞こえます。これが質問を開始します。これは 'initDoSomething'の目的は何ですか? 'CFoo 'オブジェクトを作成するために 'doSomething'が呼び出すのは単に"ジェネレータ "関数ですか?もしそうなら、それは 'static'である必要があります。なぜなら、あなたがコンストラクタ自体(つまり' this'ポインタを介して)でそうしない限り、まだ構築されていないオブジェクトに対してメソッドを呼び出すことはできないからです。 ...これがあなたが望むものであれば、 'initDoSomething'は' public'として宣言されているので、 'doSomething'は友達関数である必要はありません。 – Jason

+0

"_関数がクラスのプライベートデータメンバにアクセスする必要がある場合は、friend-functionではなくクラスのメソッドにする必要があります._"なぜですか? – curiousguy

関連する問題