The Java untuk C ++ programmer tutorial mengatakan bahwa (sorot adalah saya sendiri):
Final kata kunci kira - kira setara dengan const di C ++
Apa arti "kasar" dalam konteks ini? Bukankah mereka persis sama?
Apa perbedaannya, jika ada?
The Java untuk C ++ programmer tutorial mengatakan bahwa (sorot adalah saya sendiri):
Final kata kunci kira - kira setara dengan const di C ++
Apa arti "kasar" dalam konteks ini? Bukankah mereka persis sama?
Apa perbedaannya, jika ada?
Jawaban:
Dalam C ++ menandai fungsi anggota const
berarti dapat dipanggil pada const
instance. Java tidak memiliki yang setara dengan ini. Misalnya:
class Foo {
public:
void bar();
void foo() const;
};
void test(const Foo& i) {
i.foo(); //fine
i.bar(); //error
}
Nilai dapat ditetapkan, sekali, nanti hanya di Jawa mis.:
public class Foo {
void bar() {
final int a;
a = 10;
}
}
legal di Jawa, tetapi tidak C ++ sedangkan:
public class Foo {
void bar() {
final int a;
a = 10;
a = 11; // Not legal, even in Java: a has already been assigned a value.
}
}
Dalam Java dan C ++ variabel anggota dapat final
/ const
masing-masing. Ini perlu diberi nilai pada saat instance kelas selesai dibangun.
Di Jawa mereka harus ditetapkan sebelum konstruktor selesai, ini dapat dicapai dengan salah satu dari dua cara:
public class Foo {
private final int a;
private final int b = 11;
public Foo() {
a = 10;
}
}
Di C ++ Anda harus menggunakan daftar inisialisasi untuk memberi const
nilai pada anggota:
class Foo {
const int a;
public:
Foo() : a(10) {
// Assignment here with = would not be legal
}
};
Di Java final dapat digunakan untuk menandai hal-hal yang tidak dapat ditimpa. C ++ (pre-C ++ 11) tidak melakukan ini. Misalnya:
public class Bar {
public final void foo() {
}
}
public class Error extends Bar {
// Error in java, can't override
public void foo() {
}
}
Namun dalam C ++:
class Bar {
public:
virtual void foo() const {
}
};
class Error: public Bar {
public:
// Fine in C++
virtual void foo() const {
}
};
ini baik-baik saja, karena semantik penandaan fungsi anggota const
berbeda. (Anda juga dapat membebani dengan hanya memiliki fungsi const
salah satu anggota. (Catat juga bahwa C ++ 11 memungkinkan fungsi anggota ditandai sebagai final, lihat bagian pembaruan C ++ 11)
C ++ 11 sebenarnya memungkinkan Anda untuk menandai kedua kelas dan fungsi anggota sebagai final
, dengan semantik identik dengan fitur yang sama di Jawa, misalnya di Jawa:
public class Bar {
public final void foo() {
}
}
public class Error extends Bar {
// Error in java, can't override
public void foo() {
}
}
Sekarang dapat ditulis dengan tepat di C ++ 11 sebagai:
class Bar {
public:
virtual void foo() final;
};
class Error : public Bar {
public:
virtual void foo() final;
};
Saya harus mengkompilasi contoh ini dengan pra-rilis G ++ 4.7. Perhatikan bahwa ini tidak menggantikan const
dalam kasus ini, tetapi menambahkannya, memberikan perilaku mirip Java yang tidak terlihat dengan kata kunci C ++ setara terdekat. Jadi jika Anda ingin fungsi anggota menjadi keduanya final
dan const
Anda akan melakukannya:
class Bar {
public:
virtual void foo() const final;
};
(Urutan const
dan di final
sini diperlukan).
Sebelumnya tidak ada yang setara langsung dengan const
fungsi anggota meskipun membuat fungsi tidak virtual
akan menjadi opsi yang potensial meskipun tanpa menyebabkan kesalahan pada waktu kompilasi.
Demikian juga dengan Java:
public final class Bar {
}
public class Error extends Bar {
}
menjadi di C ++ 11:
class Bar final {
};
class Error : public Bar {
};
(Sebelumnya private
konstruktor mungkin yang paling dekat dengan C + +)
Menariknya, untuk menjaga kompatibilitas dengan kode pra-C ++ 11 final
bukanlah kata kunci dengan cara biasa. (Ambil contoh C ++ 98 yang sepele dan legal struct final;
untuk melihat mengapa menjadikannya kata kunci akan memecahkan kode)
final int a; a = 10; a = 11;
itu tidak (yang menjadi tujuan final
sebagai pengubah variabel.) Juga, anggota akhir suatu kelas hanya dapat ditetapkan pada waktu deklarasi, atau sekali dalam konstruktor .
final
dekorator fungsi anggota untuk tujuan yang tepat ini. VC ++ 2005, 2008, dan 2010 sudah menerapkan ini, menggunakan kata kunci kontekstual sealed
daripada final
.
Di Jawa, kata kunci terakhir dapat digunakan untuk empat hal:
Satu hal penting adalah: Variabel anggota akhir Java harus diset tepat sekali! Misalnya, dalam konstruktor, deklarasi lapangan, atau intializer. (Tetapi Anda tidak dapat menetapkan variabel anggota akhir dalam suatu metode).
Konsekuensi lain dari pembuatan variabel variabel anggota berkaitan dengan model memori, yang penting jika Anda bekerja di lingkungan berulir.
Sebuah const
objek hanya dapat memanggil const
metode, dan umumnya dianggap berubah.
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)
Sebuah final
objek tidak dapat diatur untuk objek baru, tetapi tidak berubah - tidak ada yang menghentikan seseorang dari menelepon setiap set
metode.
final Person person = myself;
person = otherPerson; //Invalid
person.setAge(20); //Valid!
Java tidak memiliki cara yang melekat untuk mendeklarasikan objek yang tidak dapat diubah; Anda perlu merancang kelas sebagai diri Anda sendiri yang tidak berubah.
Ketika variabel adalah tipe primitif, final
/ const
bekerja sama.
const int a = 10; //C++
final int a = 10; //Java
a = 11; //Invalid in both languages
Java final sama dengan C ++ const pada tipe nilai primitif.
Dengan tipe referensi Java, kata kunci terakhir setara dengan pointer const ... yaitu
//java
final int finalInt = 5;
final MyObject finalReference = new MyObject();
//C++
const int constInt = 5;
MyObject * const constPointer = new MyObject();
Anda sudah memiliki beberapa jawaban hebat di sini, tetapi satu hal yang sepertinya layak ditambahkan: const
dalam C ++ biasanya digunakan untuk mencegah bagian lain dari program mengubah keadaan objek. Seperti yang telah ditunjukkan, final
di java tidak dapat melakukan ini (kecuali untuk primitif) - itu hanya mencegah referensi dari diubah ke objek yang berbeda. Tetapi jika Anda menggunakan Collection
, Anda dapat mencegah perubahan pada objek Anda dengan menggunakan metode statis
Collection.unmodifiableCollection( myCollection )
Ini mengembalikan Collection
referensi yang memberikan akses baca ke elemen, tetapi melemparkan pengecualian jika modifikasi dilakukan, membuatnya sedikit seperti const
di C ++
Java final
hanya bekerja pada tipe dan referensi primitif, tidak pernah pada instance objek itu sendiri di mana kata kunci const bekerja pada apa pun.
Bandingkan const list<int> melist;
dengan final List<Integer> melist;
yang pertama membuat tidak mungkin untuk mengubah daftar, sementara yang terakhir hanya menghentikan Anda dari menetapkan daftar baru melist
.
Selain memiliki sifat multi-threading tertentu dan halus , variabel yang dideklarasikan final
tidak perlu diinisialisasi pada deklarasi!
Yaitu ini berlaku di Java:
// declare the variable
final int foo;
{
// do something...
// and then initialize the variable
foo = ...;
}
Ini tidak akan valid jika ditulis dengan C ++ const
.
Menurut wikipedia :
Biarkan saya menjelaskan apa yang saya pahami dengan contoh pernyataan switch / case.
Nilai dalam setiap pernyataan kasus harus berupa nilai konstanta waktu kompilasi dari tipe data yang sama dengan nilai sakelar.
mendeklarasikan sesuatu seperti di bawah ini (baik dalam metode Anda sebagai instance lokal, atau di kelas Anda sebagai variabel statis (tambahkan statik padanya), atau variabel instan.
final String color1 = "Red";
dan
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;
}
Kode ini tidak akan dikompilasi, jika color1
merupakan variabel kelas / instance dan bukan variabel lokal. Ini akan mengkompilasi jikacolor1
didefinisikan sebagai final statis (kemudian menjadi variabel final statis).
Ketika tidak dikompilasi, Anda akan mendapatkan kesalahan berikut
error: constant string expression required
kata kunci "const" berarti bahwa variabel Anda disimpan dalam ROM (dengan Mikroprosesor). di komputer, variabel Anda disimpan di area RAM untuk kode Majelis (RAM hanya baca). itu berarti bahwa variabel Anda tidak ada dalam RAM yang dapat ditulisi termasuk: memori statis, memori tumpukan dan memori tumpukan.
kata kunci "final" berarti bahwa variabel Anda disimpan dalam RAM yang dapat ditulisi, tetapi Anda melihat kepada kompiler bahwa variabel Anda hanya berubah satu kali saja.
//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
Saya pikir, "const" buruk dalam kinerja, jadi Java tidak menggunakannya.