次のようにクラスメンバーを宣言できます。
class Test {
public:
int a;
}
a
これが宣言方法ですが、変数が定義されている場所を知りたいです。
私は静的クラスメンバーを知っています。これは静的変数であるため、クラス内で定義することはできません。クラス外で定義する必要があります。したがって、通常のクラスメンバーには定義する場所が必要だと思います。通常のメンバーが暗黙的に定義されるのはコンストラクターだと思います。そうですか?
非静的データ メンバーの場合、宣言と定義はまったく同じです。
したがって、通常のクラスメンバーには定義する場所が必要だと思います。通常のメンバーが暗黙的に定義されるのはコンストラクターだと思います。
私はあなたがどこから来ているかを見ることができると思います。静的データ メンバーごとに、型ごとに 1 つの変数インスタンスしかありません (テンプレートの場合、テンプレートのインスタンス化ごとに異なる型が作成されます)。そのため、宣言は通常の変数の extern 宣言に似ています。どこかのアドレス - 後でアドレスをステッチするようリンカに依頼してください。」定義_プログラムがコンパイラに、その特定の翻訳単位のオブジェクト内の変数用に実際のメモリを予約するように要求する場所です。これはリンカーによって検出され、宣言に基づいて変数を認識してアクセスする他の翻訳単位内のコードにアクセスできるようになります。(テンプレートの場合はもう少し複雑です)。したがって、大まかに言えば、プログラマーの観点からは、静的データ メンバーの定義は、メモリの割り当てをトリガーし、コンストラクターの実行を準備するソース コードの行のように見えます。定義を記述したら、割り当てと構築はすべてソートされます。
ただし、非静的データメンバーの場合はまったく異なります-クラス定義がコンパイラーによって解析されるとき、そのクラスタイプのインスタンスオブジェクトがまだ存在しないため、これらの非静的データメンバーにどこかにメモリを与えるという実際の要求はまだありません. 他のコードがオブジェクト インスタンスの必要性を示している場合にのみ、コンパイラはメモリを配置し (placement を使用していない場合new
)、構築する必要があります。別の言い方をすれば、非静的データ メンバーの定義と割り当て/構築は一般に切り離されており、別のソース コードを使用しています。
これはすべて再帰的に適用されます。オブジェクト インスタンス自体が静的であるか、ファイル/名前空間スコープである場合、上記のように、定義が表示されたときにメモリと構築 (クラス内のデータ メンバーを含む) が配置されます (必ずしも実行されるとは限りません)。しかし、多くの場合、オブジェクト インスタンスはスタックまたはヒープ上にあります。どちらの方法でも、データ メンバーの割り当てと構築のコードは、それを含むオブジェクトが作成される方法によって駆動され、データ メンバーの定義とは関係ありません。
a
宣言の直後、コンストラクター内、または完全にクラス外で定義できます。a
定義できるすべての方法を示す例を次に示します。
class Test {
public:
int a = 5;
Test() {
a = 5;
}
};
int main() {
Test foo;
foo.a = 5;
return 0;
}
オブジェクトのすべてのインスタンスには、そのオブジェクト用にメモリ内に予約されたスペースが与えられます。おそらくヒープストレージまたはスタックにあります。
そのオブジェクトのすべてのメンバー変数が格納されるのは、その空間内の特定の場所です。
データ メンバーをカプセル化し、SetA()、GetA() などの特定のメソッドでその定義を管理することをお勧めします。コンストラクターで既定値を指定できます。