チュートリアルC ++プログラマのためのJava(ハイライトは自分である)ことを言います:
キーワードfinalは 、C ++のconst とほぼ同等です。
この文脈で「大まかに」はどういう意味ですか?彼らはまったく同じではありませんか?
もしあれば、違いは何ですか?
チュートリアルC ++プログラマのためのJava(ハイライトは自分である)ことを言います:
キーワードfinalは 、C ++のconst とほぼ同等です。
この文脈で「大まかに」はどういう意味ですか?彼らはまったく同じではありませんか?
もしあれば、違いは何ですか?
回答:
C ++では、メンバー関数をマークするconst
と、const
インスタンスで呼び出される可能性があります。Javaにはこれに相当するものがありません。例えば:
class Foo {
public:
void bar();
void foo() const;
};
void test(const Foo& i) {
i.foo(); //fine
i.bar(); //error
}
値は一度だけ、後でJavaでのみ割り当てることができます。例:
public class Foo {
void bar() {
final int a;
a = 10;
}
}
Javaでは合法ですが、C ++では合法ではありません。
public class Foo {
void bar() {
final int a;
a = 10;
a = 11; // Not legal, even in Java: a has already been assigned a value.
}
}
JavaとC ++の両方で、メンバー変数はそれぞれfinal
/になりconst
ます。これらには、クラスのインスタンスの構築が完了するまでに値を指定する必要があります。
Javaでは、コンストラクタが完了する前に設定する必要があります。これは、次の2つの方法のいずれかで実現できます。
public class Foo {
private final int a;
private final int b = 11;
public Foo() {
a = 10;
}
}
C ++では、const
メンバーに値を与えるために初期化リストを使用する必要があります。
class Foo {
const int a;
public:
Foo() : a(10) {
// Assignment here with = would not be legal
}
};
Javaでは、finalを使用して、オーバーライド不可としてマークを付けることができます。C ++(pre-C ++ 11)はこれを行いません。例えば:
public class Bar {
public final void foo() {
}
}
public class Error extends Bar {
// Error in java, can't override
public void foo() {
}
}
しかし、C ++では:
class Bar {
public:
virtual void foo() const {
}
};
class Error: public Bar {
public:
// Fine in C++
virtual void foo() const {
}
};
メンバ関数をマーキングの意味があるため、これは、大丈夫ですconst
異なります。(メンバー関数の1つだけをオンにすることでオーバーロードすることもできconst
ます。(C ++ 11では、メンバー関数を最終としてマークすることもできます。C++ 11の更新セクションを参照してください)
C ++ 11では、実際には、クラスとメンバー関数の両方をとしてマークすることができます。final
たとえば、JavaのJavaの同じ機能のセマンティクスは同じです。
public class Bar {
public final void foo() {
}
}
public class Error extends Bar {
// Error in java, can't override
public void foo() {
}
}
C ++ 11で次のように正確に記述できるようになりました。
class Bar {
public:
virtual void foo() final;
};
class Error : public Bar {
public:
virtual void foo() final;
};
この例をG ++ 4.7のプレリリースでコンパイルする必要がありました。const
この場合、これは置き換えられないが、それを補強して、最も近い同等のC ++キーワードでは見られなかったJavaのような動作を提供することに注意してください。したがって、メンバー関数を両方にfinal
しconst
たい場合は、次のようにします。
class Bar {
public:
virtual void foo() const final;
};
(const
およびfinal
ここの順序が必要です)。
以前は、const
メンバー関数に直接相当するものはありませんでしたが、関数を非virtual
コンパイルにすることは、コンパイル時にエラーを発生させることなく可能性のあるオプションです。
同様にJava:
public final class Bar {
}
public class Error extends Bar {
}
C ++ 11になる:
class Bar final {
};
class Error : public Bar {
};
(以前は、private
コンストラクターはおそらくC ++でこれに到達できる最も近いものでした)
興味深いことに、C ++ 11以前のコードfinal
との下位互換性を維持するために、通常の方法ではコードはキーワードではありません。(簡単で合法なC ++ 98の例struct final;
を見て、キーワードにするとコードが壊れる理由を確認してください)
final int a; a = 10; a = 11;
はそうではないことに言及する価値があります(それfinal
は変数修飾子としての目的です)。 。
final
まさにこの目的のためにメンバー関数デコレーターを追加することに注意してください。VC ++ 2005、2008、および2010にsealed
は、ではなく、contextualキーワードを使用してこれがすでに実装されていますfinal
。
Javaでは、最後のキーワードを次の4つの目的で使用できます。
重要なことの1つは、Javaの最終メンバー変数は 1回だけ設定する必要があるということです。たとえば、コンストラクター、フィールド宣言、または初期化子の中です。(ただし、メソッドで最終メンバー変数を設定することはできません)。
メンバー変数をfinalにするもう1つの結果はメモリモデルに関係します。これは、スレッド環境で作業する場合に重要です。
const
オブジェクトのみを呼び出すことができるconst
方法を、一般的に不変と考えられています。
const Person* person = myself;
person = otherPerson; //Valid... unless we declared it const Person* const!
person->setAge(20); //Invalid, assuming setAge isn't a const method (it shouldn't be)
final
オブジェクトは、新しいオブジェクトに設定されていないが、それは不変ではないことができます-任意の呼び出しから誰かを止めるものは何もないset
方法は。
final Person person = myself;
person = otherPerson; //Invalid
person.setAge(20); //Valid!
Javaには、オブジェクトを不変として宣言する固有の方法はありません。自分でクラスを不変として設計する必要があります。
変数がプリミティブ型の場合、final
/ const
は同じように機能します。
const int a = 10; //C++
final int a = 10; //Java
a = 11; //Invalid in both languages
Java finalは、プリミティブ値型のC ++ constと同等です。
Java参照型では、最後のキーワードはconstポインターと同等です...すなわち
//java
final int finalInt = 5;
final MyObject finalReference = new MyObject();
//C++
const int constInt = 5;
MyObject * const constPointer = new MyObject();
あなたはここでいくつかの素晴らしい答えをすでに持っていますが、追加する価値があると思われた1つの点:const
C ++では、プログラムの他の部分がオブジェクトの状態を変更するのを防ぐために一般的に使用されます。指摘したようにfinal
、Javaではこれを行うことができません(プリミティブを除く)- 参照が別のオブジェクトに変更されるのを防ぐだけです。ただし、を使用している場合はCollection
、静的メソッドを使用してオブジェクトへの変更を防ぐことができます
Collection.unmodifiableCollection( myCollection )
これは、Collection
要素への読み取りアクセスを提供する参照を返しますが、変更が試みられた場合は例外をスローし、const
C ++のようになります。
特定の微妙なマルチスレッドプロパティがあることを除いて、宣言された変数は宣言時final
に初期化する必要はありません!
つまり、これはJavaで有効です。
// declare the variable
final int foo;
{
// do something...
// and then initialize the variable
foo = ...;
}
これは、C ++で記述されている場合は無効ですconst
。
ウィキペディアによると:
switch / caseステートメントの例で理解したことを説明しましょう。
各caseステートメントの値は、スイッチ値と同じデータ型のコンパイル時の定数値でなければなりません。
以下のようなものを宣言します(メソッド内でローカルインスタンスとして、またはクラス内で静的変数(静的に追加します)またはインスタンス変数として)。
final String color1 = "Red";
そして
static final String color2 = "Green";
switch (myColor) { // myColor is of data type String
case color1:
//do something here with Red
break;
case color2:
//do something with Green
break;
}
color1
クラス/インスタンス変数であり、ローカル変数ではない場合、このコードはコンパイルされません。これはcolor1
、静的な最終として定義されている場合にコンパイルされます(その後、静的な最終変数になります)。
コンパイルされない場合、次のエラーが発生します
error: constant string expression required
キーワード「const」は、変数がROMに保存されることを意味します(マイクロプロセッサを使用)。コンピューターでは、変数はアセンブリコード用のRAM領域に保存されます(読み取り専用RAM)。これは、変数が書き込み可能RAMにないことを意味します:スタティックメモリ、スタックメモリ、ヒープメモリ。
キーワード「最終」は、変数が書き込み可能なRAMに保存されることを意味しますが、変数が変更されるのは1回だけであることをコンパイラに通知します。
//in java language you can use:
static final int i =10;
i =11; //error is showed here by compiler
//the same in C++ the same as follows
int i =10;
const int &iFinal = i;
iFinal = 11; //error is showed here by compiler the same as above
「const」はパフォーマンスが悪いので、Javaは使用しないと思います。