-
C++ と Java の類似点と相違点
1. ポインタ ★★★★★
C C++ のポインターは優れた柔軟性を備えていますが、ポインターの不適切な操作により、メモリ リークやダングリング ポインターなどの問題が発生しやすいという危険も伴います。
Java はポインタをキャンセルします。しかし実際には、Java で宣言されたすべての参照データ型の名前はポインタとして理解できます。名前はスタック メモリに保存され、メモリ内の new によって開かれたスペースを指します。
のように:
int[] 配列 = 新しい int[10]
整数配列名の array はスタック メモリ上にあり、10*4 バイトのスペースがヒープ メモリ上に開かれ、array はメモリのブロックを指します。
配列はポインタとして理解でき、そこに格納されるアドレスは new によって作成された空間です。
のように:
クラス人{
…
}
人 p = 新しい人();
オブジェクト名 p はスタック メモリ内で開かれ、new はオブジェクト用のヒープ メモリ内の領域を開くために使用されます。オブジェクト名 p はヒープ メモリを指します。
しかし実際には、特にパラメータを渡す場合、名前は C++ のポインタとは異なります。
Java では、パラメータの受け渡しはすべて値によると述べています。
ただし、参照データ型が関数のパラメーターとして使用される場合、宣言されたオブジェクト p1 が渡されると、この p2 は p1 を指すため、p1 から p2 のメンバーを呼び出すときに、オブジェクト p2 のコピーが実際に生成されます。変更が完了するまで待って、変更を保持します。のように:
クラス人{
パブリック文字列名。
公的整数年齢;
public Person(String name,int age){
this.name = 名前;
this.age = 年齢;
}
}
パブリック クラス Test{
public static void main(String[] args){
人物 p = 新しい人物("張三", 10);
System.out.println("修正前-->名前: "+p.name+", 年齢: "+p.age);
changePro(p); //オブジェクト p が渡され、p を指す p1 であるとします。 //このコピー p1 を通じて、p のメンバーを呼び出すことができます。
System.out.println("修正後-->名前: "+p.name+", 年齢: "+p.age);
}
public static void changePro(Person p){ //元のオブジェクトのメンバーはコピーを通じて呼び出すことができます
p.name = "李思";
ページ数 = 30;
}
}
結果:
修正前→名前:張三、年齢:10歳
修正後→名前:李思、年齢:30歳
ただし、p1 を渡すと、p2 のコピーが生成され、p1 から p2 へのポインティングを変更しようとすることは明らかに不可能です。関数呼び出しが完了した後、p2 のポインティングのみが変更されます。 p1 の値は変更されません。のように:
クラス人{
パブリック文字列名。
公的整数年齢;
public Person(String name,int age){
this.name = 名前;
this.age = 年齢;
}
}
パブリック クラス Test{
public static void main(String[] args){
人物 p = 新しい人物("張三", 10);
System.out.println("修正前-->名前: "+p.name+", 年齢: "+p.age);
changeObj(p); //p のコピーであるオブジェクト p が渡されます。これは p を指す p1 であるとします。 //関数内では、このコピーのポインタのみが変更されます。
System.out.println("修正後-->名前: "+p.name+", 年齢: "+p.age);
}
public static Person newP = new Person("李思", 30);
public static void changeObj(人 p){
p = newP; //ポインタを変更しようとしますが、実際に変更されるのはコピーのポインタです。
//関数終了後は元のオブジェクトのポインティングは変更されません
}
}
結果:
修正前→名前:張三、年齢:10歳
修正後→名前:張三、年齢:10歳
2. 動的なメモリ割り当て
C++ では、new と delete を使用してメモリを動的に割り当て、リサイクルします。New は、メモリを使用した後、手動で delete を使用してメモリをリサイクルする必要があります。
参照データ型が Java で宣言されている限り、使用前に new を使用してメモリ空間を開く必要があります。ただし、オブジェクトが消滅した後は、手動でメモリを再利用する必要はありません。 Java 独自のメモリ リサイクル メカニズムは、ガベージ オブジェクトを自動的にリサイクルします (いわゆるガベージ オブジェクトは、以前に開かれたオブジェクト メモリを指しますが、スタック メモリでは参照されなくなります)。もちろん、System.gc() メソッドを使用して手動リサイクルを実行することもできます。
3. デストラクター
C++ デストラクター (パラメーターなし、戻り値なし) の機能は、コンストラクター内で動的に割り当てられたメモリ領域を解放すること、つまり、デストラクターを呼び出すことです (この呼び出しはオブジェクトを通じて呼び出すことができます。または、システムは自動的に待機することもできます)。オブジェクトの有効期間が終了します。
Java にはデストラクターがなく、ガベージ オブジェクトはガベージ コレクション メカニズムを通じて自動的にリサイクルされます。ただし、Object クラスの fanalize() メソッドをオーバーライドすることで、C++ のデストラクターと同じ効果を得ることができます。オブジェクトが手動または自動で破棄されると、 fanalize() メソッドが自動的に呼び出されます。
4. 空のクラスの内容
C++ の空のクラスには、デフォルト コンストラクター、デフォルト デストラクター、およびデフォルト コピー コンストラクターの 4 つの関数が必要です。
Java の空のクラスには、デフォルトのコンストラクター、オブジェクト クラスから継承されたメソッド (次のようなもの) が含まれます。
クラスのデフォルト属性 C++ クラスには、パブリック > プロテクト > プライベートの 3 種類のメンバー アクセス許可があります。宣言されていない場合、デフォルトの権限はプライベートになります。
Java クラスには、パブリック > プロテクテッド > デフォルト > プライベートの 4 種類のメンバー アクセス権限があります。デフォルトはデフォルトの権限です。
5. クラスへのメンバー関数の実装
C++ では慣習的です。 h 関数はクラス外のヘッダー ファイルのクラス内で宣言されています。 cpp ファイルに関数を実装するには、ヘッダー ファイルを #include します。
のように:
//デモ.h
クラスの人{
公共:
Void fun(); //クラスで宣言
}
//デモ.cpp
#include “demo.h”
Void Person::fun(){ //クラス外の実装
。 。 。 。 //実装本体
}
Java はクラス内での宣言 + 実装メソッドです。クラスに実装されていない場合、abstract キーワードの追加は抽象メソッドです。
のように:
クラス人{
Public void fun(){//クラス内の宣言 + 実装
。 。 。 。 //実装本体
}
}
6. オブジェクトのインスタンス化
クラス人{
プライベート:
年齢;
公共:
人(){}
人(int a){
年齢 = ;
}
void fun(){….}
}
。 。 。 。 //メイン関数の開始
Person p1 //パラメータなしのコンストラクタが呼び出されます。
Person p2(18) //パラメータ化されたコンストラクタを呼び出します。
p1.fun(); //メンバー関数を呼び出す
p2.fun();
Java でオブジェクトをインスタンス化するには、new キーワードを使用する必要があります。
クラス人{
プライベート文字列名。
プライベートの年齢。
パブリック パーソン(){}
public Person(文字列名、整数の年齢){
this.name = 名前;
this.age = 年齢;
}
public void fun() {…..}
}
。 。 。 。 。 //メイン関数の開始
人 p1 = null ;
p1 = new Person(); //メモリ空間を開き、パラメータなしのコンストラクタを呼び出すには new キーワードを使用する必要があります。
Person p2 = new Person("Zhang San", 18); //パラメータ化されたコンストラクターを呼び出します。
p1.fun(); //メソッドを呼び出す
p2.fun();
7. このキーワード
C++ では this ポインターと呼ばれ、オブジェクトがインスタンス化されると、このオブジェクトを指す this ポインターがデフォルトで生成され、同じクラスの異なるオブジェクトを区別するためにコンパイラーによって使用されます。つまり、物体として。メンバー関数を使用する場合、this ポインターを通じてそれがどのオブジェクトであるかを知り、メンバー関数を呼び出してオブジェクトのメンバー プロパティを操作します。
Java ではこれには 3 つの用途があります。
1. このクラスの属性またはメソッドを表します。このようなものです。方法は、これです。財産。
2. 現在のオブジェクトを表します。
3. このクラスのコンストラクター メソッドを呼び出します。 this()、this(パラメータ 1、パラメータ 2...) など。
[使用 1 と 2 の機能は、C++ の this ポインターに似ています。 】
8. オブジェクトメンバーの呼び出し
C++ はオブジェクトを渡します。メンバー関数、またはクラス ポインター -> 呼び出すメンバー関数。
Java では、オブジェクトのみを渡すことができます。メンバー関数の呼び出し。
この 2 つの静的属性のメンバーは、クラス名を介して直接渡すことができます。メンバー関数は直接呼び出されます。
9. サブクラス --> 親クラス、コンストラクターによって渡されるパラメーターには共通点があります。サブクラスのコンストラクターが親クラスのどのコンストラクターを呼び出すかを明確に示していない場合、システムはデフォルトで親クラスのパラメーターのないコンストラクターを呼び出します。クラス。同時に、親クラスがパラメーター付きのコンストラクターを定義している場合は、パラメーターなしでコンストラクターを定義することが最善です。
クラス人{
プライベート:
年齢;
公共:
人(){}
人(int a){
年齢 = ;
}
}
クラス学生: 一般人{
プライベート:
int スコア ;
公共:
Student(int a, int s):Person(a){ //親クラスのコンストラクターに渡す
スコア = s;
}
}
クラス人{
プライベート文字列名。
プライベートの年齢。
パブリック パーソン(){}
public Person(文字列名、整数の年齢){
this.name = 名前;
this.age = 年齢;
}
}
クラス Student は Person{ を拡張します
プライベート int スコア。
public Student(文字列名、整数年齢、整数スコア){
super(name,age); //親クラスのコンストラクターに渡す
this.score = スコア;
}
}
10. ポリモーフィズム
C++ におけるポリモーフィズムは、[仮想関数または純粋仮想関数 + 仮想関数または純粋仮想関数のサブクラス カバレッジ] によって実現される必要があります。
仮想関数は virtual で宣言されます。
のように:
virtual void fun(); //クラス内での宣言
void クラス名: fun() {….}//クラス外の実装
Java は、サブクラスを使用して通常の親クラスの通常のメソッドをオーバーライドし、サブクラスを使用して抽象クラスの通常のメソッドまたは抽象メソッドをオーバーライドし、サブクラスを使用してインターフェースの抽象メソッドをオーバーライドします。 +上向きに変形します。
抽象メソッドは、abstract で宣言され、コンテンツの実装はありません。
のように:
abstract void fun(); //クラス内に実装なし
11. 抽象クラス どちらの抽象クラスもオブジェクトをインスタンス化できません。純粋仮想関数と抽象メソッドには、同様の概念と同様の機能があります。
C++ には抽象クラス、つまり純粋仮想関数を持つクラスがあるとも言えます。
純粋仮想関数は、コンテンツ実装がなく、「=0」の仮想関数であり、オブジェクトをインスタンス化できません。
のように:
virtual void fun() = 0; //クラス内では=0として宣言されており、クラス外では実装されません。
Java の抽象クラスは、abstract キーワードを使用して宣言されたクラスであり、抽象メソッドが含まれています。オブジェクトをインスタンス化できません。
Java のインターフェースは特別なクラス、または特別な抽象クラスです。これはすべての静的定数と抽象関数で構成されます。
12. アクセス権
C++ では、3 つの継承メソッドを使用して、サブクラスと親クラスの間でメンバーのアクセス権を変更します。
クラス学生: 一般人{
公共:
。 。 。 。 。 。
プライベート:
。 。 。 。 。 。
};
クラスワーカー: 保護された人物{
公共:
。 。 。 。 。 。
プライベート:
。 。 。 。 。 。
};
クラス農家: 個人{
公共:
。 。 。 。 。 。
プライベート:
。 。 。 。 。 。
};
Java は、パッケージ メカニズムを通じて、異なるクラス間のメンバーへのアクセス許可を実装します。
パッケージorg.tyut.a
クラス人{
プライベート…..
プライベート……
公共……。
公共…
}
パッケージ org.tuyt.b
クラス人{
プライベート…..
プライベート……
公共……。
公共…
}
パッケージ org.tuyt.c
クラス人{
プライベート…..
プライベート……
公共……。
公共…
}
13. C++ プリプロセス & Java インポート パッケージの考え方は同じです。現在のクラス以外のクラスを使用したい場合、
C++ では、クラス定義の前に #include プリコンパイル ディレクティブを使用して、インクルードするクラス ライブラリをインクルードします。
標準クラス ライブラリでは、h なしの山かっこ < > を使用します。カスタム クラス ライブラリで h とともに二重引用符 "" を使用すると、現在のパスから最初に検索されます。
のように:
#include <iostream>
#include “demo.h”
Java では、使用するクラスをインポートするには、import コマンドを使用して、クラスが配置されているパッケージを指定します。
のように:
java をインポートします。ラング。 *;
組織をインポートします。ティット。 *;