ホームページ バックエンド開発 PHPチュートリアル PHPにおける静的キーワードの役割

PHPにおける静的キーワードの役割

Jul 02, 2017 am 11:54 AM
php static キーワード

次の記事の要約:

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 までご連絡ください。

ホット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ヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

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

Ubuntu および Debian 用の PHP 8.4 インストールおよびアップグレード ガイド Ubuntu および Debian 用の PHP 8.4 インストールおよびアップグレード ガイド Dec 24, 2024 pm 04:42 PM

PHP 8.4 では、いくつかの新機能、セキュリティの改善、パフォーマンスの改善が行われ、かなりの量の機能の非推奨と削除が行われています。 このガイドでは、Ubuntu、Debian、またはその派生版に PHP 8.4 をインストールする方法、または PHP 8.4 にアップグレードする方法について説明します。

PHP 開発用に Visual Studio Code (VS Code) をセットアップする方法 PHP 開発用に Visual Studio Code (VS Code) をセットアップする方法 Dec 20, 2024 am 11:31 AM

Visual Studio Code (VS Code とも呼ばれる) は、すべての主要なオペレーティング システムで利用できる無料のソース コード エディター (統合開発環境 (IDE)) です。 多くのプログラミング言語の拡張機能の大規模なコレクションを備えた VS Code は、

今まで知らなかったことを後悔している 7 つの PHP 関数 今まで知らなかったことを後悔している 7 つの PHP 関数 Nov 13, 2024 am 09:42 AM

あなたが経験豊富な PHP 開発者であれば、すでにそこにいて、すでにそれを行っていると感じているかもしれません。あなたは、運用を達成するために、かなりの数のアプリケーションを開発し、数百万行のコードをデバッグし、大量のスクリプトを微調整してきました。

PHPでHTML/XMLを解析および処理するにはどうすればよいですか? PHPでHTML/XMLを解析および処理するにはどうすればよいですか? Feb 07, 2025 am 11:57 AM

このチュートリアルでは、PHPを使用してXMLドキュメントを効率的に処理する方法を示しています。 XML(拡張可能なマークアップ言語)は、人間の読みやすさとマシン解析の両方に合わせて設計された多用途のテキストベースのマークアップ言語です。一般的にデータストレージに使用されます

JSON Web Tokens(JWT)とPHP APIでのユースケースを説明してください。 JSON Web Tokens(JWT)とPHP APIでのユースケースを説明してください。 Apr 05, 2025 am 12:04 AM

JWTは、JSONに基づくオープン標準であり、主にアイデンティティ認証と情報交換のために、当事者間で情報を安全に送信するために使用されます。 1。JWTは、ヘッダー、ペイロード、署名の3つの部分で構成されています。 2。JWTの実用的な原則には、JWTの生成、JWTの検証、ペイロードの解析という3つのステップが含まれます。 3. PHPでの認証にJWTを使用する場合、JWTを生成および検証でき、ユーザーの役割と許可情報を高度な使用に含めることができます。 4.一般的なエラーには、署名検証障害、トークンの有効期限、およびペイロードが大きくなります。デバッグスキルには、デバッグツールの使用とロギングが含まれます。 5.パフォーマンスの最適化とベストプラクティスには、適切な署名アルゴリズムの使用、有効期間を合理的に設定することが含まれます。

母音を文字列にカウントするPHPプログラム 母音を文字列にカウントするPHPプログラム Feb 07, 2025 pm 12:12 PM

文字列は、文字、数字、シンボルを含む一連の文字です。このチュートリアルでは、さまざまな方法を使用してPHPの特定の文字列内の母音の数を計算する方法を学びます。英語の母音は、a、e、i、o、u、そしてそれらは大文字または小文字である可能性があります。 母音とは何ですか? 母音は、特定の発音を表すアルファベットのある文字です。大文字と小文字など、英語には5つの母音があります。 a、e、i、o、u 例1 入力:string = "tutorialspoint" 出力:6 説明する 文字列「TutorialSpoint」の母音は、u、o、i、a、o、iです。合計で6元があります

PHPでの後期静的結合を説明します(静的::)。 PHPでの後期静的結合を説明します(静的::)。 Apr 03, 2025 am 12:04 AM

静的結合(静的::) PHPで後期静的結合(LSB)を実装し、クラスを定義するのではなく、静的コンテキストで呼び出しクラスを参照できるようにします。 1)解析プロセスは実行時に実行されます。2)継承関係のコールクラスを検索します。3)パフォーマンスオーバーヘッドをもたらす可能性があります。

PHPマジックメソッド(__construct、__destruct、__call、__get、__setなど)とは何ですか? PHPマジックメソッド(__construct、__destruct、__call、__get、__setなど)とは何ですか? Apr 03, 2025 am 12:03 AM

PHPの魔法の方法は何ですか? PHPの魔法の方法には次のものが含まれます。1。\ _ \ _コンストラクト、オブジェクトの初期化に使用されます。 2。\ _ \ _リソースのクリーンアップに使用される破壊。 3。\ _ \ _呼び出し、存在しないメソッド呼び出しを処理します。 4。\ _ \ _ get、dynamic属性アクセスを実装します。 5。\ _ \ _セット、動的属性設定を実装します。これらの方法は、特定の状況で自動的に呼び出され、コードの柔軟性と効率を向上させます。

See all articles