2011-01-18 22 views
12

sbiとEli Benderskyの答えをthis questionに読み込んだ後、私はどのような静的メンバー関数があるのか​​疑問に思いました。静的メンバー関数

クラスのフレンドリーな機能はできません何か静的メンバー機能はできますか?もしそうなら、なぜ私は友人に無料の静的メンバー関数を好むべきですか?

+0

多くの場合、率直に言って、あなたはしないでください。 –

答えて

12

静的メンバ関数は、クラスのprivateメンバへのアクセス権を持っているプラ​​イベートメンバーにアクセスする必要があります。必要な場合は、静的メンバー関数を使用できます。あなたはそれをアクセス権を与えるためにヘッダーにそれを宣言しなければならないので、友人ではなくメンバーにすることもできます。これは通常、シングルトンとしてgetInstance()メソッドを持つシングルトン、および静的ファクトリメソッドcreateInstance()を使用してクラスがヒープ上に作成されるようにするクラスに対してこのように行われます。どちらもプライベートコンストラクタにアクセスする必要があります。

メタプログラミング

静的メンバ関数は、クラスに渡し、実際に呼び出されますどのような機能呼び出しの時点では知らなくても、そのメソッドを呼び出すことができ、テンプレートメタプログラミングのための非常に優れています。これは一般に「コンパイル時の多型」と呼ばれ、メタプログラミングの重要な部分です。 std :: char_traitsはこの原則に基づいています。

は、それが唯一のクラスによってアクセスすることができるだけのように、アクセス

プライベート静的メンバ関数の一般的な使用を制限し、それ自体がプライベートメンバーへのアクセスを必要としない、の良い使用ではありません静的メンバー関数はクラスの実装の詳細の一部であるため、これはコンパイル単位の匿名名前空間でうまくいきます。

ただし、静的メンバー関数がである場合、は派生クラスで呼び出すことができますが、外部クラスでは呼び出せないため、使用しています。

フレンド関数

  • は、プライベートメンバーへのアクセス権を持っていますが、とにかくヘッダ内で宣言する必要ができます。
  • メタプログラミングで「オーバーロード」の一部として使用することはできますが、ヘッダーで宣言する必要があります。 (一般的な例はoperator<<です)
  • 友人との保護されたアクセスでは機能しません。ここで何をしようとしているのかは、コールへのアクセス権ではなくメソッドへのアクセスを制限することです。
+0

どのような場合にフレンドフリー関数はテンプレートメタプログラミングで使用できませんか?テンプレート化されたフレンドリーな関数が静的メンバー関数が行うことができない何かを行うことができない例を見つけることができません。第3のポイントは良いものです、それを考えなかった!たとえば、 – peoro

+0

は特質クラスです。 traits_class :: dostuff(params); dostuffはtraits_classの静的メンバーです。 – CashCow

+0

上記の答えでは、traits_classはテンプレートパラメータであるか、テンプレートパラメータから派生したものです。 – CashCow

4

多くの場合、率直に言って、すべきではありません。無料機能は、大いにです。

静的メンバーの使用による暗黙的な「ネームスペース」は、静的メンバーの名前空間(静的メンバーの名前空間だけです。これはまさにソートです)が私が考えることができる唯一のメリットです。

静的関数メンバに永続変数が必要な場合は、静的関数メンバを静的関数メンバに追加する機能も役立ちます。

+0

+1「無料の機能は非常に過小評価されています。" –

10

静的メソッド:

  • は、クラスによって作成された "名前空間" でカプセル化を提供します。クラスがAnimalで、静的メソッドがCreateの場合は、Animal::Createで呼び出す必要があります。これはグローバル関数より優れており、比較的自然な構文でFactoriesと "virtual constructors"を実装することができます。
  • 静的メンバーにアクセスできます。そのようなメンバは、場合によっては便利です。静的メソッドやメンバを持たない場合は、グローバル変数と関数を使用する必要があります。
+1

また、クラスのインスタンスが与えられていれば、すべてのプライベートメソッドと関数にもアクセスできます(非常に便利です)。 – Macke

+0

静的クラスのメンバーはフリー関数でも見ることができ、フレンドフリー関数は非公開メソッドあなたは最初の点について正しいですが、それは構文の問題ですね。これは他の質問で言われていることと対照的ではありませんか? – peoro

+0

@peoro:(1)は主に名前空間についてですが、 (1)があると、静的メンバははるかに便利で「普通の」ものですが、静的メンバーにグローバルな機能を持たせてクラス内の友人を宣言するよりも、IMHO。 –

3

手続き上の背景から来ており、OOを理解していない人が頻繁に使用するため、静的関数を使用することを心配する人もいます。

しかし静的メンバ関数例えば

を使用して実装することが意味をなす多くのデザインパターンがあります。実際には、オブジェクト作成が必要なほとんどの構造パターンに静的メンバー関数が必要です。一般的に

+1

はい、この目的のために静的関数が使用されていますが、フレンドリーな関数は何の不都合もなく同じことができるはずです... – peoro

+0

また、グローバルデータがシングルトンで偽装されていることにも注意してください。だからここでの豊富な議論を参照してください:http://stackoverflow.com/questions/137975/...-holmes今すぐ編集 – rholmes

1

正確に識別されたとおり、staticメンバー機能に追加値はありません。さらに悪いことに、実装の詳細のために使用すると、(コンパイル時に)余分な依存関係が導入されます。

匿名のフリー関数でエミュレートできなかった使用は、protectedアクセスです。つまり、親静的関数にアクセスする派生クラスです。しかし、これは決して必要なことではありません。代わりに通常のメンバ関数にすることができます(グローバルな状態を持たないと仮定します。そうでなければ、静的/友だちの区別は直ちに問題になりません)。

テンプレートのメタプログラミングでは、static関数の使用が呼び出されました...しかし、内部型の問題に非常に似ています。デフォルトのバージョンを提供することが難しくなります。一方(ポインタとして型を取る)、適切に定義された自由な機能、テンプレートのバージョンを提案することができます

struct some_traits 
{ 
    static void doStuff(); 
}; 

// versus 

struct some_traits {}; 

void doStuff(some_traits*); 

// and the default: void doStuff(...); 

をそしてもちろん、これは静的関数であるべき理由の質問が常にありますメンバ関数がユーザにより柔軟性を提供する場合には、この効果のために、標準委員会がAllocatorのコンセプトで行った動きを挙げると、ステートフルなアロケータが許可され、与えられたmapのノードをヒープ全体に広げるのではなく、同じページにパックする機会が与えられます。

最後に、インターフェイスがあります。しかし、Sutterは同じヘッダに定義されているクラスとフリー関数の両方が、このクラスのパブリックインターフェイスを構成していると主張して以来、ずっと長いことでした。>これがADLの目的です!だから、古きよきOOプログラマーを「良い実践」よりも慰めてくれるものがあります。

実際には、staticメンバー機能を使用することによるメリットはありません。私は人々が真実の事案を提案することに反対すると思います。

関連する問題