Java Language
C ++の比較
サーチ…
前書き
JavaとC ++は類似の言語です。このトピックは、JavaおよびC ++エンジニアのクイックリファレンスガイドとして機能します。
備考
他のコンストラクトで定義されたクラス#
別のクラス内で定義される
C ++
ネストされたクラス[ref] (囲むクラスへの参照が必要です)
class Outer {
class Inner {
public:
Inner(Outer* o) :outer(o) {}
private:
Outer* outer;
};
};
Java
[静的でない]ネストされたクラス(別名内部クラスまたはメンバークラス)
class OuterClass {
...
class InnerClass {
...
}
}
別のクラス内で静的に定義される
C ++
静的ネストされたクラス
class Outer {
class Inner {
...
};
};
Java
静的入れ子クラス(別名静的メンバークラス) [ref]
class OuterClass {
...
static class StaticNestedClass {
...
}
}
メソッド内で定義される
(例えば、イベント処理)
C ++
ローカルクラス[ref]
void fun() {
class Test {
/* members of Test class */
};
}
ラムダ式も参照
Java
ローカルクラス[ref]
class Test {
void f() {
new Thread(new Runnable() {
public void run() {
doSomethingBackgroundish();
}
}).start();
}
}
オーバーライド対オーバーロード
次のOverriding vs Overloadingポイントは、C ++とJavaの両方に適用されます。
- オーバーライドされたメソッドは、基本メソッドと同じ名前と引数を持ちます。
- オーバーロードされたメソッドは同じ名前ですが、引数が異なり、継承に依存しません。
- 同じ名前と引数を持ち、戻り値の型が異なる2つのメソッドは不正です。関連するStackoverflowの質問を参照してください "異なる戻り値の型でJavaでオーバーロードする" - 質問1 。 質問2
多型
多相性とは、継承によって関連する異なるクラスのオブジェクトが同じメソッド呼び出しに異なる応答をする能力です。ここに例があります:
- 基底クラス抽象メソッドとして領域を持つ形状
- SquareクラスとCircleクラスの2つの派生クラスは、エリアメソッドを実装しています
- Square参照点とSquareが呼び出されます
C ++では、仮想メソッドによって多態性が有効になります。 Javaでは、メソッドはデフォルトでは仮想です。
建設/破壊の命令
オブジェクトのクリーンアップ
C ++では、デストラクタを仮想として宣言して、ベースクラスのポインタが削除された場合にサブクラスのデストラクタが確実に呼び出されるようにすることをお勧めします。
Javaでは、finalizeメソッドはC ++のデストラクタと似ています。ただし、ファイナライザは予測できません(GCに依存しています)。ベストプラクティス - 明示的にクリーンアップするには、「クローズ」メソッドを使用します。
protected void close() {
try {
// do subclass cleanup
}
finally {
isClosed = true;
super.close();
}
}
protected void finalize() {
try {
if(!isClosed) close();
}
finally {
super.finalize();
}
}
抽象メソッドとクラス
概念 | C ++ | Java |
---|---|---|
抽象メソッド 実装なしで宣言された | 純粋仮想メソッドvirtual void eat(void) = 0; | 抽象メソッドabstract void draw(); |
抽象クラス インスタンス化することはできません | インスタンス化することはできません。少なくとも1つの純粋仮想メソッドを持つclass AB {public: virtual void f() = 0;}; | インスタンス化することはできません。非抽象メソッドを持つことができるabstract class GraphicObject {} |
インタフェース インスタンスフィールドなし | "interface"キーワードはありませんが、抽象クラスの機能を持つJavaインタフェースを模倣することができます | 抽象クラスに非常に似ていますが、1)多重継承をサポートしています。 2)インスタンスフィールドなしinterface TestInterface {} |
アクセシビリティ修飾子
モディファイア | C ++ | Java |
---|---|---|
公開 - すべてのユーザーがアクセス可能 | 特別なメモはありません | 特別なメモはありません |
保護された - サブクラスによってアクセス可能 | 友達からもアクセス可能 | 同じパッケージ内でアクセス可能 |
私的 - メンバーがアクセス可能 | 友達からもアクセス可能 | 特別なメモはありません |
デフォルト | クラスのデフォルトはprivateです。構造体のデフォルトはpublicです。 | 同じパッケージ内のすべてのクラスからアクセス可能 |
その他 | フレンド - 継承のないプライベートおよび保護されたメンバーへのアクセスを許可する方法(下記参照) |
C ++の友達の例
class Node {
private:
int key; Node *next;
// LinkedList::search() can access "key" & "next"
friend int LinkedList::search();
};
恐ろしいダイヤモンドの問題
ダイアモンドの問題は、2つのクラスBとCがAから継承し、クラスDがBとCの両方から継承するときに生じるあいまいさです。AにBとCがオーバーライドされ、Dがそれをオーバーライドしないメソッドがある場合、どのバージョンのメソッドにDが継承しますか:Bのそれ、またはCのそれは継承しますか? ( ウィキペディアから)
C ++は常にダイアモンドの問題を抱えていましたが、JavaはJava 8まで影響を受けていましたが、Javaは複数の継承をサポートしていませんでしたが、デフォルトのインタフェースメソッドの出現によりJavaクラスは複数のクラス。
java.lang.Objectクラス
Javaでは、すべてのクラスは暗黙的または明示的にObjectクラスから継承されます。どのJava参照もObject型にキャストできます。
C ++には、同等の「オブジェクト」クラスがありません。
JavaコレクションとC ++コンテナ
JavaコレクションはC ++コンテナと同義です。
Javaコレクションのフローチャート
C ++コンテナのフローチャート
整数型
ビット | 分 | 最大 | C ++型 (LLP64またはLP64の場合) | Javaタイプ |
---|---|---|---|---|
8 | -2(8-1)= -128 | 2(8-1)-1 = 127 | チャー | バイト |
8 | 0 | 2(8)-1 = 255 | 署名されていないchar | - |
16 | -2(16-1)= -32,768 | 2(16-1)-1 = 32,767 | ショート | ショート |
16 | 0(\ u0000) | 2(16)-1 = 65,535(\ uFFFF) | 署名のない短い | char(符号なし) |
32 | -2(32-1)= -2.147億 | 2(32-1)-1 = 21.47億 | int | int |
32 | 0 | 2(32)-1 = 42億9500万 | 符号なし整数 | - |
64 | -2(64-1) | 2(16-1)-1 | 長いです* | 長く長い |
64 | 0 | 2(16)-1 | 符号なしlong * 符号なしlong long | - |
*
Win64 APIはわずか32ビットです
静的クラスメンバー
静的メンバーはオブジェクトスコープではなくクラススコープを持ちます
C ++の例
// define in header
class Singleton {
public:
static Singleton *getInstance();
private:
Singleton() {}
static Singleton *instance;
};
// initialize in .cpp
Singleton* Singleton::instance = 0;
Javaの例
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if(instance == null) {
instance = new Singleton();
}
return instance;
}
}
他のコンストラクト内で定義されたクラス
別のクラス内で定義される
C ++
ネストされたクラス[ref] (囲むクラスへの参照が必要です)
class Outer {
class Inner {
public:
Inner(Outer* o) :outer(o) {}
private:
Outer* outer;
};
};
Java
[静的でない]ネストされたクラス(別名内部クラスまたはメンバークラス)
class OuterClass {
...
class InnerClass {
...
}
}
別のクラス内で静的に定義される
C ++
静的ネストされたクラス
class Outer {
class Inner {
...
};
};
Java
静的入れ子クラス(別名静的メンバークラス) [ref]
class OuterClass {
...
static class StaticNestedClass {
...
}
}
メソッド内で定義される
(例えば、イベント処理)
C ++
ローカルクラス[ref]
void fun() {
class Test {
/* members of Test class */
};
}
Java
ローカルクラス[ref]
class Test {
void f() {
new Thread(new Runnable() {
public void run() {
doSomethingBackgroundish();
}
}).start();
}
}
値渡しと参照渡し
多くの人が、Javaは単なる値渡しだと主張していますが、それよりも微妙です。以下のC ++とJavaの例を比較して、値渡し(別名コピー)と参照渡し(別名別名)の多くの味を見てください。
C ++の例(コード全体)
// passes a COPY of the object
static void passByCopy(PassIt obj) {
obj.i = 22; // only a "local" change
}
// passes a pointer
static void passByPointer(PassIt* ptr) {
ptr->i = 33;
ptr = 0; // better to use nullptr instead if '0'
}
// passes an alias (aka reference)
static void passByAlias(PassIt& ref) {
ref.i = 44;
}
// This is an old-school way of doing it.
// Check out std::swap for the best way to do this
static void swap(PassIt** pptr1, PassIt** pptr2) {
PassIt* tmp = *pptr1;
*pptr1 = *pptr2;
*pptr2 = tmp;
}
Javaの例(完全なコード)
// passes a copy of the variable
// NOTE: in java only primitives are pass-by-copy
public static void passByCopy(int copy) {
copy = 33; // only a "local" change
}
// No such thing as pointers in Java
/*
public static void passByPointer(PassIt *ptr) {
ptr->i = 33;
ptr = 0; // better to use nullptr instead if '0'
}
*/
// passes an alias (aka reference)
public static void passByAlias(PassIt ref) {
ref.i = 44;
}
// passes aliases (aka references),
// but need to do "manual", potentially expensive copies
public static void swap(PassIt ref1, PassIt ref2) {
PassIt tmp = new PassIt(ref1);
ref1.copy(ref2);
ref2.copy(tmp);
}
継承と構成
C ++とJavaはどちらもオブジェクト指向言語なので、次の図は両方に適用されます。
流出したダウンキャスティング
"ダウンキャスティング"を使用することに注意してください - ダウンキャスティングは、継承階層をベースクラスからサブクラス(すなわち、多型の反対)にキャストしています。一般に、instanceof&downcastingの代わりにpolymorphism&overridingを使用します。
C ++の例
// explicit type case required
Child *pChild = (Child *) &parent;
Javaの例
if(mySubClass instanceof SubClass) {
SubClass mySubClass = (SubClass)someBaseClass;
mySubClass.nonInheritedMethod();
}
抽象メソッドとクラス
抽象メソッド
実装なしで宣言された
C ++
純粋仮想メソッド
virtual void eat(void) = 0;
Java
抽象メソッド
abstract void draw();
抽象クラス
インスタンス化することはできません
C ++
インスタンス化することはできません。少なくとも1つの純粋仮想メソッドを持つ
class AB {public: virtual void f() = 0;};
Java
インスタンス化することはできません。非抽象メソッドを持つことができる
abstract class GraphicObject {}
インタフェース
インスタンスフィールドなし
C ++
Javaに匹敵するものは何もない
Java
抽象クラスに非常に似ていますが、1)多重継承をサポートしています。 2)インスタンスフィールドなし
interface TestInterface {}