C++前提で話します。
static修飾子がありますが、classを使っていてstaticが必要だと思ったことがありません。
staticでできることは理解していますがやはり使う機会はありません。
そもそもオブジェクト指向的にstaticって矛盾していませんか?
オブジェクト指向を完全に理解しているわけではないので全く見当違いなことを言っていたら申し訳ないです。
もしオブジェクト指向的におかしくないのなら、どのような場面でstaticは便利なのでしょうか?
追記
staticが必要になってくるというのは分かりました。
では、積極的にstaticにした方が良いのでしょうか?
そこまで複雑なコードを書いてきていないからかもしれませんが、staticにしても問題ないという変数や関数に遭遇していません(遭遇しているが気づいていないかもしれませんが)。どうしてもstaticに違和感があります。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

回答8件
0
こんにちは。
staticなメンバは、名前空間内に定義したグローバル変数、グローバル関数と大差ありません。
つまり、これらはオブジェクト指向プログラミングというよりは、多くの場合は手続き型プログラミングと思います。(シングルトン・バターン等、オブジェクト指向プログラミングに分類した方が良いものもあります。)
では、オブジェクト指向プログラミングさえあれば、手続き型プログラミングが完全に不要かと言うとそんなことはありません。やはり必要な場面はでてきます。
その時、クラスのstaticメンバで実装するのか、通常のグローバル関数/グローバル変数で実装するのかは、大差はないように感じます。
よりクラスと強く結びついた機能ならstaticメンバでしょうし、例えば、他のクラスもサポートするようなあまりクラスとの結びつきが強くないものはグローバル関数/変数を選択するだろうと思います。
【追記への回答】
では、積極的にstaticにした方が良いのでしょうか?
staticと非static、どちらかが良いかはその要件で決定できると思います。
クラスをインスタンス化する度に必要なメモリなら非staticメンバ変数です。
その非staticメンバ変数を操作する関数なら概ね非staticメンバ関数でしょう。(こちらは例外があるかもしれません。)
クラスに対して1つだけ存在して欲しいメモリならstaticメンバ変数です。
一切の非staticメンバをアクセスしないなら概ねstaticメンバ関数でしょう。(たまたまアクセスしていないだけで、本質的にはアクセスしても可笑しくない場合は非staticで実装することもあるでしょう。)
投稿2017/06/08 07:46
編集2017/06/08 12:47総合スコア23274
0
投稿2017/06/08 07:38
総合スコア80888
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
コールバックされる関数はstaticでないといけませんよね。非staticなメンバー関数は暗黙でthisポインタが渡されるので、クラスのインスタンスと無関係なところからコールされるようにはできません。
また、全てのインスタンスにかかわる設定をstaticなメンバー変数として保存しておいたりします。
ファイルを出力するクラスを作ったとして、改行をLFにするかCR+LFにするかはファイルごとに異なることよりもすべてのファイルで同じ設定を使うことが多いと思います(テキストエディタのようなソフトでは別ですが)。そうであれば、設定を変更した場合に、全てのインスタンスの設定を変えるよりも、staticなメンバー変数の内容を変えるほうが楽になります。
投稿2017/06/08 07:55
総合スコア249
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
オブジェクト指向の最も重要な要素である「カプセル化」の観点から見たら、むしろstatic
はオブジェクト指向的に無くてはならないものだと思います。
static
がなければグローバル変数や手続き型の関数を使わざるを得なくなってしまいます。
どうしてもstaticに違和感があります。
クラスに紐付いた情報をカプセル化したものがstaticメンバ。
そのstaticメンバを扱うための関数がstaticメソッドと考えればスッキリしませんか?
では、積極的にstaticにした方が良いのでしょうか?
staticメンバとインスタンスに属するメンバは、役割が根本的に違いますので交換可能ではありません。
すべてのインスタンスで共通の値を持ちたい場合はstaticメンバ、インスタンスごとに個別の値を持ちたい場合は非staticメンバになります。
微々たるものですが、適切にstaticにした方がthisポインタを経由したりスタックに積まないので速度的にもメモリ的にも有利です。
投稿2017/06/08 11:27
編集2017/06/08 14:34総合スコア930
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
そもそもオブジェクト指向的にstaticって矛盾していませんか?
同感です。
class ベースのオブジェクト指向なら全部インスタンス化しろよ
という意見もあるでしょうが、それだとコスト的に見合わない
場合があるので、苦肉の策って感じなのでしょうか。
使わずに済むならそうすれはせいいと思いますし、
必要な局面が出てきたら使う。
そんくらいのスタンスでいいと思いますよ~
投稿2017/06/08 09:02
総合スコア7468
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
一般的な場面は他の方が述べているようですのでちょっと変わり種の用途としては、テンプレートと組み合わせて型を識別するような値を作りたいというような場合ですね。
説明しづらいので簡単なコードを示します。
cpp
1#include <iostream> 2 3template<class T> struct foo { 4 static int tag; 5 const int* tag_pointer = &tag; 6 template<class U> 7 bool operator==(foo<U> x) { 8 return tag_pointer == x.tag_pointer; 9 } 10}; 11 12template<class T> int foo<T>::tag = 0; 13 14int main(void) { 15 foo<int> x, y; 16 foo<double> z; 17 18 std::cout << "x==y = " << (x==y) << std::endl; 19 std::cout << "x==z = " << (x==z) << std::endl; 20}
このときテンプレートクラス foo
の型引数 T
は使われません。 いわゆる幽霊型 (Phantom type) です。 しかし T
に当て嵌められた型ごとに foo
は実体化されるので、上述の例では static
なメンバである foo<T>::tag
は foo<int>::tag
と foo<double>::tag
のふたつが作られることになります。 もちろんそれぞれ違う場所に作られるのでその変数のアドレスは型ごとに異なります。
普通は type_info
を使う方が簡単なのですが、本格的なメタプログラミングでは活用したりもするみたいです。
投稿2017/06/08 08:16
総合スコア5714
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
他にも、クラスのメンバー関数を_beginthreadする場合はstaticであることが要求されます。以下のように別のstaticなメンバー関数を噛ませて非staticなメンバー関数をスレッドとして実行する方法がありますが、結局staticな関数は必要なわけで。
オブジェクト指向的にどうのこうというより、現実問題として必要な場面があるということになるかと。
C++
1class Test { 2:private 3 HANDLE thread; // スレッドハンドル 4 5 // スレッド開始 6 void threadStart(){ 7 thread = (HANDLE) _beginthread( 8 &test::executeLauncher, // ランチャを起動 9 0, 10 this); 11 } 12 13 // ランチャ 14 static void executeLauncher(void* args){ 15 // 無理やりtest*型にキャストして、本命の処理を実行する。 16 reinterpret_cast<test*>(args)->execute(); 17 } 18 19 // 本命の処理(非staticメンバ変数) 20 void execute(){ 21 … 22 } 23}; 24 25main(){ 26 Test test = new Test(); 27 // スレッドで、staticではないメンバ変数execute()が実行 28 test->threadStart(); 29}
投稿2017/06/08 08:11
総合スコア3579
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。