検索
ホームページバックエンド開発PHPチュートリアルPHPにおける静的キーワードの役割
PHPにおける静的キーワードの役割Jul 02, 2017 am 11:54 AM
phpstaticキーワード

次の記事の要約:

1. 静的変数の場合: ローカライズ (名前の競合)、初期化 = 0、一意の共有 (静的領域)。特に、クラスの静的メンバー変数の場合: (1) クラス全体に属し、インスタンスを介する代わりにクラス名を介して直接アクセスできます。 (2) 初期化され、クラス内で static として宣言され、クラスの外部で初期化される必要があります (static追加することはできません)

2 .クラスの静的メンバー関数の場合、(1) this ポインターはなく、静的メンバー変数と静的メンバー関数のみにアクセスでき、仮想関数として宣言することはできません (2) のサブクラスでよく使用されます。マルチスレッド。

------------------------------------------------ -------------------------------------------------- --------------------------------------------------

1. static とは何ですか?
static は、C++ で変数の保存方法と可視性を制御するために使用されます。 S 2. 静的変数で定義された変数を導入するのはなぜですか? プログラムがその定義に従って実行されると、コンパイラーはスタック上に関数によって割り当てられたスペースを関数上で実行することを誰もが知っています。実行 最後に解放されますが、次の呼び出しまで関数内のこの変数の値を保存したい場合、どうすればそれを実現できるでしょうか?という疑問が生じます。 最も簡単に考えられる方法は、グローバル変数を定義することですが、グローバル変数として定義すると多くの欠点があります。最も明らかな欠点は、この変数のアクセス スコープが破壊されることです (この関数で定義された変数が制御されるだけではなくなります)。この機能)。

3. static を使用するのはどのような場合ですか?
特定のオブジェクトではなくクラス全体にサービスを提供するデータ オブジェクトが必要であり、同時にクラスのカプセル化を破壊しないようにする必要があります。つまり、このメンバーはクラス内に隠蔽され、外の世界には見えません。

4. 静的の内部メカニズム:
静的データ メンバーは、プログラムの実行開始時に存在する必要があります。関数はプログラムの実行中に呼び出されるため、関数内で静的データ メンバーを割り当てたり初期化したりすることはできません。

このように、スペース割り当てには 3 つの場所が考えられます。1 つはクラスの外部インターフェイスとしてのヘッダー ファイルで、2 つはクラス定義の内部実装です。クラスのメンバー関数定義、3 番目は main() 関数の前のアプリケーションのグローバル データ宣言と定義です。

静的データ メンバーは実際に領域を割り当てる必要があるため、クラスの宣言で定義できません (宣言できるのはデータ メンバーのみです)。クラス宣言はクラスの「サイズと仕様」を宣言するだけで、実際のメモリ確保は行いませんので、クラス宣言に定義を書くのは間違いです。また、ヘッダー ファイルのクラス宣言の外で定義することもできません。その場合、そのクラスを使用する複数のソース ファイルで再定義されることになります。引 Static は、スタック上の領域ではなくプログラムの静的記憶領域に変数が初期化されたことをコンパイラに通知するために導入されました。削除の順序は初期化の逆の順序です。

5. 静的の利点:
すべてのオブジェクトに共通であるため、メモリを節約できます。したがって、複数のオブジェクトの場合、静的データ メンバーはすべてのオブジェクトで共有される 1 つの場所にのみ保存されます。静的データ メンバーの値はすべてのオブジェクトで同じですが、その値は更新できます。静的データ メンバーの値が一度更新される限り、すべてのオブジェクトは同じ更新された値にアクセスすることが保証されるため、時間効率が向上します。

6. 静的データ メンバーを参照する場合は、次の形式を使用します。

、静的データ メンバーは、上記の形式に従ってプログラム内で参照できます。

7. 注意事項:
(1)クラスの静的メンバー関数は、クラスのオブジェクトではなくクラス全体に属しますので、このポインターを持たず、その結果、静的メンバー関数のみにアクセスしますクラスメンバー関数のデータと静的データ。
(2) 静的メンバー関数は仮想関数として定義できません。
(3) 静的メンバーはクラス内で宣言され、その外部で動作するため、そのアドレスを取得する操作は若干特殊です。変数 address はそのデータ型 へのポインターであり、関数のアドレス型は「非メンバー」です。関数ポインター”。

(4) 静的メンバー関数にはこのポインターがないため、非メンバー関数とほぼ同等になります。その結果、予想外の利点が得られます。これにより、C++ と C を組み合わせることができます。ベースの X Window システムであると同時に、スレッド関数への適用にも成功しました。
(5) static は、プログラムの時間とスペースのオーバーヘッドを増加させません。それどころか、親クラスの静的メンバーへのサブクラスのアクセス時間も短縮され、サブクラスのメモリスペースが節約されます。 ️ (6) する場合、静的データ メンバーの前にキーワード static が付けられます。
(7)
静的データメンバーは静的に格納されるため、初期化する必要があります。 (8) 静的メンバーの初期化は、一般的なデータ メンバーの初期化とは異なります:
use using using using out out through out クラス本体の ‐ ‐ ‐ ‐‐‐‐‐
制御記号 Private、Public など。 スコープ演算子
のスコープを使用して、初期化時に所属するクラスを指定します。 =
(9) 親クラスの影響を防ぐために、次のように定義できます。親クラスの影響をシールドするために、親クラスと同じサブクラス内の静的変数。ここで注意すべき点が 1 つあります。静的メンバーは親クラスとサブクラスで共有されると言っていますが、静的メンバーを繰り返し定義するとエラーが発生しますか?いいえ、私たちのコンパイラは、名前のマングリングという気の利いたトリックを使用して一意の識別子を生成します。

静的データメンバー

クラスにおいて、静的メンバーは複数のオブジェクト間でのデータ共有を実現することができ、静的データメンバーを使用することで隠蔽の原理を崩さない、つまり安全性が保証されます。したがって、静的メンバーは、特定のオブジェクトのメンバーではなく、クラスのすべてのオブジェクト間で共有されるメンバーです。

静的データ メンバーを使用すると、すべてのオブジェクトに共通であるため、メモリを節約できます。したがって、複数のオブジェクトの場合、静的データ メンバーはすべてのオブジェクトで共有される 1 つの場所にのみ保存されます。静的データ メンバーの値はすべてのオブジェクトで同じですが、その値は更新できます。静的データ メンバーの値が一度更新される限り、すべてのオブジェクトは同じ更新された値にアクセスすることが保証されるため、時間効率が向上します。

静的データメンバーの使用方法と注意事項は以下のとおりです。

1. 静的データメンバーの定義または説明の前にキーワード static を追加します。

2. 静的メンバーの初期化は、一般的なデータメンバーの初期化とは異なります。静的データメンバの初期化形式は以下の通りです:

::=

これは以下を示します:

(1)での初期化一般的な静的変数やオブジェクトとの混同を避けるために、前に static を追加せずにクラスの外側で実行されます。

(2) 初期化中にメンバーのアクセス制御文字 private、public などを追加しないでください。

(3) 初期化中にスコープ演算子を使用して、それが属するクラスを示します。 したがって、静的データメンバーはオブジェクトではなくクラスのメンバーです。

3. 静的データメンバーは静的に保存されるため、初期化する必要があります。

4. 静的データメンバーを参照する場合は、次の形式を使用します:

::

静的データメンバーのアクセス権が許可している場合(つまり、パブリックメンバー)を使用すると、プログラム内で上記の形式に従って静的データ メンバーを参照できます。

静的メンバー関数

静的メンバー関数は静的データメンバーと同じです。どちらもクラスの静的メンバーであり、オブジェクトのメンバーではありません。したがって、静的メンバーへの参照ではオブジェクト名を使用する必要はありません。

静的メンバー関数の実装では、クラスに記述された非静的メンバーを直接参照することはできませんが、クラスに記述された静的メンバーは参照できます。静的メンバー関数で非静的メンバーを参照する必要がある場合は、オブジェクトを通じて参照できます。


例を見てみましょう:

#
include
 <iostream.h>
class Point
{
public:
void output()
{
}
static void init()
{  
} 
};
void main( void )
{
Point pt;
pt.init();
pt.output(); 
}

このようにコンパイルするとエラーは発生しません。
こんな感じ

#include <iostream.h>
class Point
{
public:
void output()
{  
}
static void init()
{  
} 
};
void main( void )
{
Point::output();
}

このようにコンパイルすると、エラーメッセージ:illegalcallofnon-staticmemberが発生します。 機能 、なぜですか? クラスの特定のオブジェクトがインスタンス化されていない場合、クラスにはメモリ空間が割り当てられないためです。
さて、次の例を見てください:

#include <iostream.h>
class Point
{
public:
void output()
{  
}
static void init()
{  
} 
};
void main( void )
{
Point::init();
}

クラスが定義されるとき、その静的データとメンバー関数は独自のメモリ領域を持ち、どのメモリ領域にも属さないため、現時点ではコンパイルでエラーは発生しません。特定のオブジェクトの一部。

次の例を見てください:

#include <iostream.h>
class Point
{
public:
void output()
{  
}
static void init()
{ 
   x = 0;
   y = 0;
}
private:
int x;
int y;
};
void main( void )
{
Point::init();
}

コンパイル エラー:


illegal 静的 member のデータ member 'Point::x' function
illegal 静的メンバー
メンバー関数内のデータメンバー「Point::y」への参照静的メンバー関数では、データメンバーが誤って参照されています
問題は依然として同じであり、静的メンバーです。 (関数 ) が特定のオブジェクトに属していない場合、クラスの特定のオブジェクトが宣言される前にすでにメモリ領域が存在し、非静的データ メンバーにメモリ領域が割り当てられていない場合、ここでの呼び出しは間違っています。宣言されていない場合と同じです。変数を事前に使用する場合と同じです。
つまり、静的メンバー関数では非静的メンバー変数を参照できません。
それでは、以下の例を見てみましょう:

#include <iostream.h>class Point{public:void output(){   x = 0;   y = 0;   init();  }static void init(){
}private:int x;int y;};void main( void ){Point::init();}

好的,这样就不会有任何错误。这最终还是一个内存模型的问题,
任何变量在内存中有了自己的空间后,在其他地方才能被调用,否则就会出错。
好的再看看下面的例子:

#include <iostream.h>
class Point
{
public:
void output()
{ 
}
static void init()
{ 
   x = 0;
   y = 0;
}
private:
static int x;
static int y;
};
void main( void )
{
Point::init();
}

编译:
Linking...
test.obj : error LNK2001: unresolved external symbol "private: static int Point::y" 
test.obj : error LNK2001: unresolved external symbol "private: static int Point::x" 
Debug/Test.exe : fatal error LNK1120: 2 unresolved externals
执行 link.exe 时出错.
可以看到编译没有错误,连接错误,这又是为什么呢?
这是因为静态的成员变量要进行初始化,可以这样:

#include <iostream.h>
class Point
{
public:
void output()
{ 
}
static void init()
{ 
   x = 0;
   y = 0;
}
private:
static int x;
static int y;
};
int Point::x = 0;
int Point::y = 0;
void main( void )
{
Point::init();
}

在静态成员数据变量初始化之后就不会出现编译错误了。
再看看下面的代码:

#include <iostream.h>
class Point
{
public:
void output()
{ 
}
static void init()
{ 
   x = 0;
   y = 0;
}
private:
static int x;
static int y;
};
void main( void )
{
}

编译没有错误,为什么?
即使他们没有初始化,因为我们没有访问x,y,所以编译不会出错。  

C++会区分两种类型的成员函数:静态成员函数和非静态成员函数。这两者之间的一个重大区别是,静态成员函数不接受隐含的this自变量。所以,它就无法访问自己类的非静态成员。

在某些条件下,比如说在使用诸如pthread(它不支持类)此类的多线程库时,就必须使用静态的成员函数,因为其地址同C语言函数的地址兼容。这种铜限制就迫使程序员要利用各种解决办法才能够从静态成员函数访问到非静态数据成员。

第一个解决办法是声明类的所有数据成员都是静态的。运用这种方式的话,静态的成员函数就能够直接地访问它们,例如:

class Singleton
{
public:
   static Singleton * instance();
private:
   Singleton * p;
   static Lock lock;
};
Singleton * Singleton::instance()
{
lock.getlock(); 
// fine, lock is static
if (!p)
   p=new Singleton;
lock.unlock();
return p;
}


这种解决方法不适用于需要使用非静态数据成员的类。

访问非静态数据成员

将参照传递给需要考量的对象能够让静态的成员函数访问到对象的非静态数据:

class A
{
public:
   static void func(A & obj);
   intgetval() const; 
//
non-static
 
member
 
function
private:
intval;
};


静态成员函数func()会使用参照obj来访问非静态成员val

voidA::func(A & obj)
{
   int n = obj.getval();
}


将一个参照或者指针作为静态成员函数的自变量传递,就是在模仿自动传递非静态成员函数里this自变量这一行为。

以上がPHPにおける静的キーワードの役割の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
php怎么把负数转为正整数php怎么把负数转为正整数Apr 19, 2022 pm 08:59 PM

php把负数转为正整数的方法:1、使用abs()函数将负数转为正数,使用intval()函数对正数取整,转为正整数,语法“intval(abs($number))”;2、利用“~”位运算符将负数取反加一,语法“~$number + 1”。

php字符串有没有下标php字符串有没有下标Apr 24, 2022 am 11:49 AM

php字符串有下标。在PHP中,下标不仅可以应用于数组和对象,还可应用于字符串,利用字符串的下标和中括号“[]”可以访问指定索引位置的字符,并对该字符进行读写,语法“字符串名[下标值]”;字符串的下标值(索引值)只能是整数类型,起始值为0。

php怎么除以100保留两位小数php怎么除以100保留两位小数Apr 22, 2022 pm 06:23 PM

php除以100保留两位小数的方法:1、利用“/”运算符进行除法运算,语法“数值 / 100”;2、使用“number_format(除法结果, 2)”或“sprintf("%.2f",除法结果)”语句进行四舍五入的处理值,并保留两位小数。

php怎么读取字符串后几个字符php怎么读取字符串后几个字符Apr 22, 2022 pm 08:31 PM

在php中,可以使用substr()函数来读取字符串后几个字符,只需要将该函数的第二个参数设置为负值,第三个参数省略即可;语法为“substr(字符串,-n)”,表示读取从字符串结尾处向前数第n个字符开始,直到字符串结尾的全部字符。

php怎么根据年月日判断是一年的第几天php怎么根据年月日判断是一年的第几天Apr 22, 2022 pm 05:02 PM

判断方法:1、使用“strtotime("年-月-日")”语句将给定的年月日转换为时间戳格式;2、用“date("z",时间戳)+1”语句计算指定时间戳是一年的第几天。date()返回的天数是从0开始计算的,因此真实天数需要在此基础上加1。

php怎么查找字符串是第几位php怎么查找字符串是第几位Apr 22, 2022 pm 06:48 PM

查找方法:1、用strpos(),语法“strpos("字符串值","查找子串")+1”;2、用stripos(),语法“strpos("字符串值","查找子串")+1”。因为字符串是从0开始计数的,因此两个函数获取的位置需要进行加1处理。

php怎么设置implode没有分隔符php怎么设置implode没有分隔符Apr 18, 2022 pm 05:39 PM

在PHP中,可以利用implode()函数的第一个参数来设置没有分隔符,该函数的第一个参数用于规定数组元素之间放置的内容,默认是空字符串,也可将第一个参数设置为空,语法为“implode(数组)”或者“implode("",数组)”。

php怎么判断有没有小数点php怎么判断有没有小数点Apr 20, 2022 pm 08:12 PM

php判断有没有小数点的方法:1、使用“strpos(数字字符串,'.')”语法,如果返回小数点在字符串中第一次出现的位置,则有小数点;2、使用“strrpos(数字字符串,'.')”语句,如果返回小数点在字符串中最后一次出现的位置,则有。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

このプロジェクトは osdn.net/projects/mingw に移行中です。引き続きそこでフォローしていただけます。 MinGW: GNU Compiler Collection (GCC) のネイティブ Windows ポートであり、ネイティブ Windows アプリケーションを構築するための自由に配布可能なインポート ライブラリとヘッダー ファイルであり、C99 機能をサポートする MSVC ランタイムの拡張機能が含まれています。すべての MinGW ソフトウェアは 64 ビット Windows プラットフォームで実行できます。

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

WebStorm Mac版

WebStorm Mac版

便利なJavaScript開発ツール