クラスとオブジェクトの最初のエントリ(c ++)

まず、C++のクラスとオブジェクトを次の観点から理解しましょう。

1.プロセス指向およびオブジェクト指向

C ++を学ぶ前に、まずプロセス指向とオブジェクト指向を理解する必要があります。これにより、C ++をよりよく学ぶことができるように、まずそれらの定義を見てみましょう。

プロセス指向:プロセス指向とは、問題を解決するために必要なステップを分析し、関数を使用してこれらのステップを段階的に実装し、使用時に1つずつ呼び出すことです。

オブジェクト指向:オブジェクト指向は、問題を構成するトランザクションをさまざまなオブジェクトに分解することです。オブジェクトを確立する目的は、ステップを完了することではなく、問題解決ステップ全体での何かの動作を説明することです。実生活のものはオブジェクトと見なすことができます)

その定義を知った後、私たちの一般的に使用されるC言語はプロセス指向言語であり、C ++はオブジェクト指向言語であることがわかりますが、C ++は純粋なオブジェクト指向言語ではなく、オブジェクト指向に基づく->両方プロセス指向とオブジェクト指向があります。

2.クラスとオブジェクトの紹介

クラスとは何ですか?

クラス:エンティティ(オブジェクト)、オブジェクトの属性、オブジェクトの機能を説明するために使用されます。カスタムタイプです。クラスが定義された後は、クラスにデータを直接格納することはできません。

オブジェクトとは何ですか?

オブジェクト:実生活に存在し、オブジェクトはクラスの具体的な実施形態であり、オブジェクトはクラスタイプによって作成された変数であり、オブジェクトはデータを格納できます(オブジェクトはクラスのインスタンス化と見なすことができます)

みんなの理解のために例を挙げましょう。友人の中には結婚年齢に達している人や、家族がすでに結婚を勧めている人がいると思います。現時点では、ガールフレンドがいるのは当然ですが、ガールフレンドがいない場合は、多くの都市でブラインドデートをする必要があります。オフラインのブラインドデートの「広場」では、ブラインドデートをしたい人やその親戚や友人が、他の人が理解できるようにこの人の情報を紙に印刷します。として:年齢、仕事、性別、身長、趣味、教育など、そしてこの一枚の紙は、その特定の人とこの一枚の紙に対応する人の情報の説明であるクラスと見なすことができますオブジェクト、実際のオブジェクトです。

3.クラスの定義

1.クラス

class className
{
 // 类体:由成员函数和成员变量组成
 
}; // 一定要注意后面的分号

2.struct

struct className
{
 // 类体:由成员函数和成员变量组成
 
}; // 一定要注意后面的分号

クラスを定義するためのキーワードには、structとclassの2種類があります。structで定義されたクラスメンバーのデフォルトのアクセス許可はpublicです(アクセス許可がわからない場合は、次のアクセス修飾子が表示されます)。デフォルトのアクセス権限はプライベートであり、それを定義する方法は2つあります。1つ目はクラス宣言と定義をクラス定義に入れることです。2つ目はクラス宣言をヘッダーに配置することです。ファイルであり、クラス定義は元のファイルに配置されます(通常、メソッド2を使用して定義します)。

説明のために例としてクラスを取り上げましょう。

方法1:クラス宣言と定義を元のファイルのクラス本体に配置します。

 方法2:ヘッダーファイルで宣言し、元のファイルで定義します。

4.カプセル化とクラスアクセス修飾子

C ++を学習しているので、オブジェクト指向の3つの主要な特性(4つの特性)を知る必要があります。カプセル化、継承、ポリモーフィズム(4つの特性について話している場合は、抽象化を追加します。抽象化は複雑なものの認識です。プロセス)、この記事ではパッケージのみを紹介します。

カプセル化とは何ですか?

 カプセル化は、データとデータを操作するメソッドの有機的な組み合わせであり、オブジェクトの属性と実装の詳細を非表示にし、オブジェクトと対話するためのインターフェイスのみを公開します(機能は一種のカプセル化であり、コンピューターや携帯電話もカプセル化です)

C ++はカプセル化をどのように具体化しますか?

データとデータを操作するメソッドの有機的な組み合わせはクラスと見なすことができ、オブジェクトの属性と実装の詳細を非表示にし、オブジェクトと対話するためのインターフェイスのみを公開することはアクセス権と見なすことができます。クラス外で直接アクセス

アクセス修飾子(アクセス権)とは何ですか?

クラス内のメンバー変数とメンバー関数を制限するために使用されます。publicによって制限されたメンバー変数とメンバー関数は、クラスの外部から直接アクセスできます。protectedとprivateによって制限されたメンバー変数とメンバー関数は、クラスの外部から直接アクセスできません。また、アクセス許可の範囲は、アクセス修飾子が表示される場所から始まり、次のアクセス修飾子が表示されるまでです。詳細については、次のコードを参照してください。

1.ヘッダーファイルでクラスを宣言するときに、メンバー変数とメンバー関数の両方へのパブリックアクセスを追加しました。つまり、クラスの外部で直接アクセスでき、最初のパブリックの役割に注意を払うことができます。スコープは次のとおりです。次のパブリックが表示される前から後まで、2番目のパブリックの範囲は次のとおりです:クラスの後から終わりまで。

 このとき、mainのクラスの入出力に直接アクセスしましたが、明らかにアクセスは成功し、コードは問題なく正常に実行されました。

2.ヘッダーファイルでクラスを宣言するときに、メンバー変数とメンバー関数へのプライベートアクセスを追加しました。これは、クラスの外部で直接アクセスできないことを意味します。

 このとき、mainで入力と出力に再度アクセスすると、プログラムがエラーを報告し、アクセス修飾子の役割を示すプロンプトを生成することがわかります。

クラススコープ:

上の図では、クラス内のメンバー関数がクラスの外部で定義されている場合、それらはすべてclassname :: member関数の形式であることがわかります。これは、クラスのスコープによるものです。クラスは新しいスコープを定義します。 、クラスクラスのすべてのメンバーはクラスのスコープ内にあります。クラス外のメンバーを定義するには、::スコープリゾルバーを使用して、メンバーが属するクラススコープを示す必要があります。

5.クラスオブジェクトのサイズを計算します

a。空でないクラスのサイズ

クラスオブジェクトのサイズを尋ねるには、まずクラスオブジェクトに何が含まれているかを知る必要があります。実際の検証の結果、オブジェクトにはメンバー変数のみが含まれていることがわかりました。したがって、オブジェクトのサイズは、 C言語、メモリの配置に注意してください。

実際の検証:

または、上記のコード:クラス内のメンバー変数の数とタイプを何度も変更し、sizeof()を使用してクラスとオブジェクトのサイズを直接出力したところ、そのサイズはメンバー変数にのみ関連していることがわかりました。その計算方法はC言語と同じです。構造のサイズは似ているので、メモリの配置に注意を払う限り、クラス内の「メンバー変数」の合計を見つけることができます。

では、具体的な計算方法は何ですか?まず、構造体のメモリアライメントルールを理解する必要があります。

1.最初のメンバーは、構造体からオフセット0のアドレスにあります。

2.他のメンバー変数は、アライメント番号の整数倍のアドレスにアライメントする必要があります。

3.配置=コンパイラのデフォルトの配置とメンバーのサイズの小さい方。(vsデフォルトは8)

4.構造体の合計サイズは次のとおりです。最大アライメント数の整数倍(すべての変数タイプの中で最大で、デフォルトのアライメントパラメータが最小になります)。

5.構造体がネストされている場合、ネストされた構造体はそれ自体の最大整列数の整数倍に整列され、構造体の全体のサイズはすべての最大整列数(ネストされた構造体の整列数を含む)の整数になります。 。

次に、次のルールを使用して詳細に計算します。

ステップ1:最初に最初のメンバーbの位置を見つけ、0バイトから開始し、1バイトを占有し、次に2番目のメンバーaの位置を確認します。aのアライメント番号は4(4 <8)なので、 4バイト目から開始して4バイト後方を占め、3番目のメンバーcの位置を見ると、cのアラインメント番号は8(8と8はどちらかを取るに等しい)なので、cは最初の8バイトから開始します。後方に8バイトを占有し、次に4番目のメンバーdの位置を見ると、dのアラインメント番号は4(4 <8)であるため、dは16バイトから後方に4バイトを占有し始めます。

ステップ2:次に、クラスの合計サイズを次のように判断します。最大アライメント数の倍数は24です。

b。空のクラスのサイズ

空のクラスのサイズを0とすると、空のクラスを使用してオブジェクトを作成する場合、空のクラスのサイズが0であるため、複数のオブジェクトを連続して作成すると問題が発生します。作成されたオブジェクトのサイズはも0なので、そうではありません。このスペースを占めるので、すべてのオブジェクトがこの場所に作成され、それらのアドレスは同じです。これらのオブジェクトをどのように区別できますか?答えは、それらを区別する方法がないということです。 C ++は、これを回避するために特に空のクラスを対象としています。空のクラスのサイズは0にならないように指定されており、このような状況は自然に発生しません。通常、空のクラスのサイズは1バイトに設定されますが、コンパイラが異なれば、異なる場合もあります。

6.このポインタ

1.オブジェクトを使用してクラスのメンバー関数を呼び出す場合、そのような疑問がありますか?クラスのメンバー関数にオブジェクトの説明がないため、オブジェクトを使用してこれらのメソッドを呼び出します。次の紹介は、この問題を解決するのに役立つと思います。

まず、構造体を使用してC言語で関数を呼び出す方法を考えてみましょう。通常、構造体変数のアドレスが関数に渡され、次に->記号を使用して構造体のデータを操作します。詳細は次のとおりです。

下の左側はC言語で構造体変数を呼び出すプロセスであるため、関数は構造体変数のデータを認識できますが、右側のC ++でメンバー関数にオブジェクトのデータを認識させるにはどうすればよいですか?次に見下ろします。 。

2. C ++の逆アセンブル命令から直接問題を確認できます。3つのパラメーターがスタックにプッシュされた後、C ++呼び出しメンバー関数は終了しませんが、オブジェクトdのアドレスはメンバー関数のレジスタecxに配置されます。したがって、C ++で関数呼び出しが行われる場合、データの操作に変数のアドレスが使用されるのはC言語に似ていると結論付けることができます。

3.誰もがこのポインターの役割を理解する必要があると思います。その定義を見てみましょう。C++はこのポインターを導入することで問題を解決し、C++コンパイラーは各「非静的メンバー関数」に非表示のポインターパラメーターを追加します。 "、ポインタが現在のオブジェクト(関数を呼び出すオブジェクト)を指すようにします。関数本体では、"メンバー変数 "のすべての操作はこのポインタを介してアクセスされますが、すべての操作はユーザーに対して透過的です。ユーザーは自分で渡す必要はありません。コンパイラーが自動的にそれを完了します。したがって、次の関数呼び出しの場合、実際の形式は次のようになります。

d1.Init(3,15、2022);(オブジェクト呼び出しメソッド)この時点で、コンパイラは呼び出しを----> Data :: Init(&d1,3,15,2022);に変換します。

ここでの&d1の場所は、このポインターの場所であり、関数本体のデータにアクセスするには、->この記号を使用して、データ操作のd1のアドレスを解決しますが、C ++では、これらの操作はコンパイラーによって非表示になり、透過的です。 。、そしてユーザーがパスして解析する必要がない場合、コンパイラーは完了を支援します。したがって、最終的にはC ++を使用して上記のコードを記述しますが、基本的な実装原則はC言語と同じですが、コンパイラは、隠れた部分を完成させるのに役立ちます。

注:1。このスコープは、クラス「メンバー関数」内にあります。

          2. thisポインターはnullにすることができます。メンバー関数でthisポインターにアクセスしない限り、プログラムには影響しません。次に、nullポインターをthisに渡し、メンバー関数を呼び出します。これでこのポインタのアドレスはnullですが、プログラムはクラッシュしません。

したがって、このポインタについて、次の特性を要約できます。

1.このポインタの型:class type * const

2.「メンバー関数」内でのみ使用できます。

3. thisポインターは、実際にはメンバー関数の仮パラメーターです。オブジェクトがメンバー関数を呼び出すと、オブジェクトアドレスが実際のパラメーターとしてthisパラメーターに渡されるため、thisポインターはオブジェクトに格納されません。

4. thisポインターは、メンバー関数の最初の暗黙のポインターパラメーターです。通常、コンパイラーはecxレジスターを介して自動的に渡されるため、ユーザーが渡す必要はありません。

おすすめ

転載: blog.csdn.net/weixin_49312527/article/details/123527693