Boost :: asioの例の request parser を見ていましたが、なぜis_char()
のようなプライベートメンバー関数がstatic
?なのか疑問に思っていました。 :
_class request_parser
{
...
private:
static bool is_char(int c);
...
};
_
関数で使用されます consume これは静的関数ではありません:
_boost::tribool request_parser::consume(request& req, char input)
{
switch (state_)
{
case method_start:
if (!is_char(input) || is_ctl(input) || is_tspecial(input))
{
return false;
}
...
_
メンバー関数のみがis_char()
を呼び出すことができ、静的メンバー関数はis_char()
を呼び出していません。これらの関数が静的である理由はありますか?
この関数は、クラス内のオブジェクトを操作する必要がないため、簡単に自立させることができます。関数をフリー関数ではなくクラスの静的メンバーにすることには、2つの利点があります。
この場合、2番目のポイントのみが適用されるように見えます。
これらの関数が静的である理由はありますか?
static
以外のメンバー関数には、this
と呼ばれる非表示の追加パラメーターがあります。これを渡すことは無料ではありません。そのため、private
関数static
を作成することは、optimizationの手段として見ることができます。
しかし、それはあなたのコードであなたの要件/設計を表現する手段として見ることもできます:その関数はクラスのメンバーデータを参照する必要はありませんが、なぜそれが非static
メンバー関数である必要がありますか?
ただし、メンバー関数のタイプを変更する場合は、public
またはprivate
、static
であるかどうかにかかわらず、すべてのクライアントを再コンパイルする必要があります。これらのクライアントが決して使用できないprivate
関数に対してこれを行う必要がある場合、それはリソースの無駄です。したがって、私は通常、できるだけ多くの関数をクラスのプライベート部分から実装ファイルの名前のない名前空間に移動します。
この特定の例では、static is_char()
の選択はほとんどの場合ドキュメント化です。 is_char()
メソッドはクラスの特定のインスタンスに制約されないが、機能クラス自体に固有であることを印象付けることを目的としています。
言い換えると、それをstatic
にすることで、彼らはis_char()
が特定のインスタンスの状態に関係なく使用できる一種のユーティリティ関数であると言っているのです。 private
にすることで、彼らは(クライアントとして)あなたがそれを使用しようとすべきでないと言っています。あなたが思っていることをしないか、非常に制約された、制御された方法で実装されています。
@Mark Ransomの答えは、プライベートな静的メンバー関数を実際に使用するための良いポイントをもたらします。具体的には、そのメンバー関数は、静的オブジェクトまたはインスタンス化されたオブジェクトの渡されたインスタンスのプライベートおよび保護されたメンバーにアクセスできます。
これの一般的な用途の1つは、オブジェクト指向の方法でpthread実装を抽象化することです。スレッド関数は静的である必要がありますが、プライベート関数として宣言すると、クラスへのその関数のアクセス可能性が制限されます(最も決定的なもの以外)。スレッドは、「非表示」になっているクラスのインスタンスを渡すことができ、オブジェクトのメンバーデータを使用してロジックを実行するアクセス権を持っています。
簡単な例:
[MyWorkerClass.h]
...
public:
bool createThread();
private:
int getThisObjectsData();
pthread_t myThreadId_;
static void* myThread( void *arg );
...
[MyWorkerClass.cpp]
...
bool MyWorkerClass::createThread()
{
...
int result = pthread_create(myThreadId_,
NULL,
myThread),
this);
...
}
/*static*/ void* MyWorkerClass::myThread( void *arg )
{
MyWorkerClass* thisObj = (MyWorkerClass*)(arg);
int someData = thisObj->getThisObjectsData();
}
...
request_parser
オブジェクトのメンバー変数にアクセスする必要がないため、静的です。したがって、関数がアクセスできる状態の量を減らすため、静的にすると関数が分離されます。
価値があるのは、この関数がrequest_parser
クラスの一部でなかった場合、さらに優れていたはずです。代わりに、.cpp
ファイル内の(おそらく名前空間内の)無料の関数でなければなりませんでした。
ポイントはwhereではありません。問題はwhatが使用することです。その定義が非静的メンバーを使用しない場合、冗長なパラメーターを関数に渡さないという同じ原則に従って、関数を静的にします(オーバーロードの結果で使用される場合を除く)