C ++のクラスの静的メンバー変数のクエリ
質問
この質問が多くの人にとって些細なものであると思われる場合はごめんなさい。
C ++コードには次のようなものがあります:
class Foo
{
public:
static int bands;
...
...
private:
...
...
}//class definition ends
int Foo::bands; //Note: here its not initialized to any value!
-
クラス内でstaticとして 'bands'が宣言されたときに、なぜ上記のステートメントが再び必要なのですか?
-
静的変数を任意のクラスのプライベートメンバー変数として宣言することもできますか?
解決
C ++では、宣言と定義の違いに注意してください。 bands
はクラス内で宣言されていますが、定義されていません。
非静的データメンバーは、そのタイプのオブジェクトを定義すると定義されますが、静的メンバーは特定のオブジェクトの一部ではないため、独自の定義が必要です。
他のヒント
a)それは言語が設計される方法だからです。
b)静的変数はデフォルトのコンストラクターによって初期化されます。組み込み型の場合はゼロに初期化されます。
c)はい、プライベートにすることができます(通常はプライベートです)。
objファイル、それらの使用方法、およびグローバルスコープの変数のメモリアドレスがリンクプロセスを通じて最終的に検出される方法に関係しています。オブジェクトファイルには、対応するcppで定義されているすべてのグローバルデータと関数のアドレスが含まれています。これらのグローバルなvars / funcsがそのファイル内のどこにあるかをライカーに伝えるために、いくつかのメモリを相対的な方法でレイアウトします。たとえば、
function doFoo can be found 0 bytes from beginning of this file
int foo::bands can be found 12 bytes from beginning of this file
etc
以前にストレートCを実行したことがある場合は、考えるのがほとんど簡単です。純粋なCの世界では、より伝統的なモジュラープログラミングの意味で物事を行うでしょう。モジュールはヘッダーとcppで定義されます。ヘッダーは、「パブリック」を定義します。 externキーワードを使用して以下のような変数を作成し、cppでインスタンス化します。
foo.h
extern int bands;
foo.cpp
#include "foo.h"
int bands;
foo.obj:
int bands can be found 0 bytes from the beginning of this file
" extern"キーワードは、この名前が有効であり、そのアドレスがリンク時に解決されることを示しています。 " foo.h"を含む全員「バンド」を使いたいグローバル変数が使用できるようになりました。リンク時に、リンカーはfoo.objにバンドが存在することを把握します。 「intバンド」を入れるのを忘れた場合foo.objでは、リンカーエラーが発生し、解決する必要があります。
C ++では、クラス宣言でstaticを使用しています。 " foo :: bands"と呼ばれるものが存在することをユーザーに伝えています。それがどこに存在するかは、リンク時に解決されます。その後、リンカはfoo.objにfoo :: bandsが存在することを確認し、foo :: bandsへのすべての参照を解決できます。
私の理解では、Foo :: bandsを宣言する必要があるのは、クラスのインスタンスを作成する前にFoo :: bandsを使用する予定だった場合のみです。基本的に、C ++クラスでstaticを宣言すると、そのクラスのすべてのインスタンスに対してその変数のコピーが1つだけ存在します。ただし、通常、クラスのインスタンスが宣言されるまでFoo :: bandsにアクセスできません。
例:
#include <iostream>
using namespace std;
class X {
public:
int a;
void f(int b) {
cout << "The value of b is "<< b << endl;
}
};
int main() {
// declare pointer to data member
int X::*ptiptr = &X::a;
// declare a pointer to member function
void (X::* ptfptr) (int) = &X::f;
// create an object of class type X
X xobject;
// initialize data member
xobject.*ptiptr = 10;
cout << "The value of a is " << xobject.*ptiptr << endl;
// call member function
(xobject.*ptfptr) (20);
}