これは私の前の質問の範囲の拡大です。
「静的」とは正確には何ですか、それはどのように使用されますか、そしてC ++を扱うときに「静的」を使用する目的は何ですか?
ありがとう。
これは、変数が変換ユニットに対してローカルであり(簡単に言えば、単一のソースファイルに対して)、外部からアクセスできないことを意味します。この静的な使用は、実際には現在のC ++標準では非推奨です。代わりに、匿名の名前空間を使用することになっています。
static int x = 0;
する必要があります:
namespace {
int x = 0;
}
static
C ++では、コンテキストに応じてキーワードの意味が異なります。
フリー関数またはグローバル変数を宣言する場合、この関数はこの単一の変換ユニットの外部では使用できないことを意味します。
// test.cpp
static int a = 1;
static void foo() {}
a
その翻訳ユニットをコンパイルした結果が、シンボルを含む別の翻訳ユニットにリンクされていfoo
て、この特定の翻訳ユニットのように単一定義規則に違反せず、プライベートシンボルa
でfoo
ある場合。この使用は、名前のない名前空間によって廃止されました。
// test2.cpp
namespace {
static int a = 1;
static void foo() {}
}
関数内でローカル変数を宣言する場合、変数の存続期間は、呼び出しの期間だけでなく、関数の最初の呼び出しからプログラムの最後まで延長されることを意味します。
int foo() {
static int counter = 0;
return ++counter;
}
int main() {
for ( int i = 0; i < 10; ++i ) {
std::cout << foo() << std::endl;
}
}
前のコードでcounter
は、が初めて呼び出されたときに1回初期化さfoo
れますが、変数は関数よりも長持ちし、さまざまな関数呼び出しにわたって値を保持します。前のコードは「123 4...10」を出力します。変数が宣言されていない場合static
、出力は「1 1 1...1」になります。
クラススコープ内でstatic
は、メンバーがクラスのメンバーであり、特定のインスタンスのメンバーではないことを意味します。この使用法は、他の質問での使用法と同等です。その特定のメンバーの使用法は、特定のオブジェクトにバインドされていません。
struct test {
int x;
static int y;
};
int test::y; // need to define it in one translation unit
int main() {
// test::x = 5; // !error cannot access a non-static member variable
// without an instance
test::y = 5; // ok
test t, other;
t.x = 10; // ok
t.y = 15; // ok, the standard allows calling a static member through
// an instance, but this is the same as test::y
}
この場合、メンバーx
は非静的メンバー属性であるx
ため、クラスのインスタンスごとに異なります。サンプルプログラムで、さまざまな整数t.x
を参照してください。other.x
一方、y
はstatic
であり、したがって、プログラム内に単一のインスタンスがありますtest::y
。標準で呼び出しが許可されていてt.y
、other.y
両方の使用法が同じ変数を参照している場合でも。同じことがメンバーメソッドにも当てはまります。それらが静的である場合、それらはクラスレベルのメソッドであり、インスタンスなしで呼び出すことができますが、非静的である場合、それらは具象インスタンスに適用され、a.b
ora->b
構文を使用する必要があります。
この使用法はstatic
、Javaでの同じキーワードの使用法に似ていますが、他の2つはその言語には存在しません。C ++には存在しないJavaでのキーワードの使用法が1つあります。それは、静的クラス初期化子(で囲まれたクラスレベルのコードのブロックstatic { ... }
)の使用です。Javaでは、そのコードブロックは、クラスがロードされたときに1回だけ実行されます。C ++での静的メンバー変数の初期化は、変数定義の初期化子で行う必要があります。
このようなものはここでかなりよくカバーされているようです。
しかし言い換えると、Cには2つの用途があります
次のように、関数内のローカル変数が関数の呼び出し全体で持続できるようにします。
int getNextId(){static int id = 0; id++を返します。}
C ++はこれらの両方を継承し、独自の2つの使用法を追加します。
静的とは、基本的に、変数がプログラムの存続期間に関連付けられており、特定の関数やクラスインスタンスの存続期間に関連付けられていないことを意味します。いつ使うべきですか?しないでください。目的は何ですか?ほとんどの場合、データのデバッグ。
一般に、C ++では、静的データを使用していることに気付いた場合、それは間違っています。適切な場合もありますが、非常にまれです。
staticがC++のクラスで使用される場合、それはJavaで使用するのとほぼ同じことを意味します。変数の場合、すべてのクラスと関数に対して変数の1つのインスタンスが存在することを意味します。つまり、関数がこのポインターに暗黙的にアクセスしないことを意味します。
CおよびC++では、静的がグローバル変数または関数に使用されている場合、その変数は現在のCまたはC++ファイルでのみ参照できることを意味します。つまり、コンパイラは変数または関数の再配置シンボルを生成してはなりません。
ローカル関数の変数の横でstaticが使用されている場合、その変数はスコープ外にはなりませんが、関数呼び出しから関数呼び出しまでその値を保持することを意味します。変数は事実上、指定された関数からのみアクセスできるグローバル変数になります。
静的クラスメンバーは、クラスのオブジェクトではなく、クラス自体に関連付けられているデータと関数です。
次の例では、クラスFredに静的データメンバーx_とインスタンスデータメンバーy_があります。作成されたFredオブジェクトの数(Fredオブジェクトなしを含む)に関係なく、Fred :: x_のコピーは1つだけですが、Fredオブジェクトごとに1つのy_があります。したがって、x_はクラスに関連付けられていると言われ、y_はクラスの個々のオブジェクトに関連付けられていると言われます。同様に、クラスFredには静的メンバー関数f()とインスタンスメンバー関数g()があります。
class Fred {
public:
static void f() throw(); <-- 1
void g() throw(); <-- 2
protected:
static int x_; <-- 3
int y_; <-- 4
};
(1)クラスに関連付けられたメンバー関数
(2)クラスの個々のオブジェクトに関連付けられたメンバー関数
(3)クラスに関連付けられたデータメンバー
(4)クラスの個々のオブジェクトに関連付けられたデータメンバー
使用法:
作成されたクラスのインスタンスの数を把握したい場合は、静的変数を使用します。たとえば、「Car」クラスでは、各Carインスタンスに一意のシリアル番号(この場合は_y)があり、会社は生産された車の数(この場合は_x)を追跡したい場合があります。