Öğretici C ++ programcıları için Java ki (vurgulamak benimkisi) diyor ki:
Final anahtar kelimesi kabaca C ++ 'da const ile eşdeğerdir
"Kabaca" bu bağlamda ne anlama geliyor? Tam olarak aynı değiller mi?
Varsa, farklılıklar nelerdir?
Öğretici C ++ programcıları için Java ki (vurgulamak benimkisi) diyor ki:
Final anahtar kelimesi kabaca C ++ 'da const ile eşdeğerdir
"Kabaca" bu bağlamda ne anlama geliyor? Tam olarak aynı değiller mi?
Varsa, farklılıklar nelerdir?
Yanıtlar:
C ++ işaretlemesinde üye işlevi const
, const
örneklerde çağrılabileceği anlamına gelir . Java'nın buna eşdeğer bir değeri yoktur. Örneğin:
class Foo {
public:
void bar();
void foo() const;
};
void test(const Foo& i) {
i.foo(); //fine
i.bar(); //error
}
Değerler, bir kez, daha sonra yalnızca Java ile atanabilir, örneğin:
public class Foo {
void bar() {
final int a;
a = 10;
}
}
Java'da yasaldır, ancak C ++ değil:
public class Foo {
void bar() {
final int a;
a = 10;
a = 11; // Not legal, even in Java: a has already been assigned a value.
}
}
Hem Java hem de C ++ üye değişkenlerinde sırasıyla final
/ olabilir const
. Bunlara, sınıfın bir örneğinin oluşturulmasını tamamlayana kadar bir değer verilmelidir.
Java'da yapıcı bitmeden önce ayarlanmalıdırlar, bu iki yoldan biriyle gerçekleştirilebilir:
public class Foo {
private final int a;
private final int b = 11;
public Foo() {
a = 10;
}
}
C ++ 'da const
üyelere bir değer vermek için başlatma listelerini kullanmanız gerekir :
class Foo {
const int a;
public:
Foo() : a(10) {
// Assignment here with = would not be legal
}
};
Java'da final, işleri geçersiz kılınamaz olarak işaretlemek için kullanılabilir. C ++ (C ++ öncesi 11) bunu yapmaz. Örneğin:
public class Bar {
public final void foo() {
}
}
public class Error extends Bar {
// Error in java, can't override
public void foo() {
}
}
Ancak C ++ ile:
class Bar {
public:
virtual void foo() const {
}
};
class Error: public Bar {
public:
// Fine in C++
virtual void foo() const {
}
};
üye bir işlevi işaretlemenin anlambilimi const
farklı olduğu için bu iyidir . (Ayrıca üye işlevlerinden yalnızca birine sahip olarak aşırı yükleyebilirsinizconst
. (Ayrıca, C ++ 11'in üye işlevlerinin son olarak işaretlenmesine izin verdiğini unutmayın, C ++ 11 güncelleme bölümüne bakın)
C ++ 11 aslında hem sınıfları hem de üye işlevlerini final
, Java'daki aynı özelliğe, örneğin Java'daki aynı semantikle işaretlemenize izin verir :
public class Bar {
public final void foo() {
}
}
public class Error extends Bar {
// Error in java, can't override
public void foo() {
}
}
Artık C ++ 11 ile tam olarak şu şekilde yazılabilir:
class Bar {
public:
virtual void foo() final;
};
class Error : public Bar {
public:
virtual void foo() final;
};
Bu örneği G ++ 4.7'nin ön sürümüyle derlemem gerekiyordu. Bunun const
bu durumda değiştirilmediğini , aksine artırdığını ve en yakın eşdeğer C ++ anahtar sözcüğüyle görülmeyen Java benzeri davranışı sağladığını unutmayın. Bir üye işlevinin her ikisinin de olmasını istiyorsanız final
ve const
bunu yapsaydınız:
class Bar {
public:
virtual void foo() const final;
};
(Sırası const
ve final
burada gereklidir).
Önceden const
üye işlevlerinin doğrudan eşdeğeri yoktu, ancak işlevleri virtual
derleme zamanında bir hataya neden olmadan potansiyel bir seçenek olmazdı.
Aynı şekilde Java:
public final class Bar {
}
public class Error extends Bar {
}
C ++ 11'de olur:
class Bar final {
};
class Error : public Bar {
};
(Önceden private
yapıcılar muhtemelen C ++ ile bu kadar yakın olabilirdi)
İlginç bir şekilde, C ++ 11 öncesi kod ile geriye dönük uyumluluğu korumak için her zamanki gibi bir anahtar kelime final
değildir . ( struct final;
Neden bir anahtar kelime yapmanın kodu bozacağını görmek için önemsiz, yasal C ++ 98 örneğini alın )
final int a; a = 10; a = 11;
( final
değişken değiştirici olarak amaç olduğunu) belirtmek gerekir . Ayrıca, bir sınıfın son üyeleri yalnızca bildirim zamanında veya bir yapıcıda bir kez ayarlanabilir .
final
bu tam amaç için üye işlevi dekoratör eklediğini unutmayın . VC ++ 2005, 2008 ve 2010, içeriğe dayalı anahtar kelime sealed
yerine bunu zaten uyguladı final
.
Java'da son anahtar kelime dört şey için kullanılabilir:
Önemli bir şey: Bir Java nihai üye değişkeni gerekir tam olarak bir kez ayarlanabilir! Örneğin, bir kurucuda, alan bildiriminde veya başlatıcıda. (Ancak bir yöntemde son üye değişkeni ayarlayamazsınız).
Üye değişkeni sonlandırmanın bir başka sonucu da, dişli bir ortamda çalışmanız durumunda önemli olan bellek modeli ile ilgilidir.
Bir const
nesne sadece const
yöntemleri çağırabilir ve genellikle değişmez olarak kabul edilir.
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)
Bir final
nesne yeni bir nesneye ayarlanamaz, ancak değişmez değildir - birisinin herhangi bir set
yöntem çağırmasını engelleyen hiçbir şey yoktur .
final Person person = myself;
person = otherPerson; //Invalid
person.setAge(20); //Valid!
Java'nın nesneleri değişmez ilan etmenin doğal bir yolu yoktur; sınıfı kendiniz değişmez olarak tasarlamanız gerekir.
Değişken ilkel bir tür olduğunda final
/ const
aynı şekilde çalışır.
const int a = 10; //C++
final int a = 10; //Java
a = 11; //Invalid in both languages
Java finali, ilkel değer türlerindeki C ++ sabitine eşdeğerdir.
Java başvuru türlerinde, son anahtar kelime bir sabit işaretçiye eşdeğerdir ... yani
//java
final int finalInt = 5;
final MyObject finalReference = new MyObject();
//C++
const int constInt = 5;
MyObject * const constPointer = new MyObject();
Burada zaten bazı harika cevaplarınız var, ancak eklemeye değer gibi görünen bir nokta var: const
C ++ 'da programın diğer bölümlerinin nesnelerin durumunu değiştirmesini önlemek için yaygın olarak kullanılır. Belirtildiği gibi, final
java'da bunu yapamaz (ilkeller hariç) - sadece referansın farklı bir nesneye değiştirilmesini önler . Ancak a Collection
kullanıyorsanız, statik yöntemi kullanarak nesnelerinizdeki değişiklikleri önleyebilirsiniz
Collection.unmodifiableCollection( myCollection )
Bu Collection
, öğelere okuma erişimi sağlayan bir başvuru döndürür , ancak değişiklikler denenirse bir istisna atar const
ve C ++ ' da biraz benzer hale getirir.
Java final
sadece ilkel türler ve referanslar üzerinde çalışır, asla const anahtar sözcüğünün herhangi bir şey üzerinde çalıştığı nesne örneklerinde kendileri üzerinde çalışmaz.
Karşılaştırma const list<int> melist;
ile final List<Integer> melist;
ikincisi sadece yeni bir liste atayarak alıkoyar ederken, imkansız listeyi değiştirmek için ilk marka melist
.
Belirli ve ince çok iş parçacıklı özelliklere sahip olmanın yanı sıra, beyan edilen değişkenlerin final
bildirimde başlatılması gerekmez!
ie Bu, Java için geçerlidir:
// declare the variable
final int foo;
{
// do something...
// and then initialize the variable
foo = ...;
}
C ++ 'larla yazılırsa bu geçerli olmaz const
.
Vikipedi göre :
Anladığım şeyi bir switch / case ifadesi örneğiyle açıklayayım.
Her vaka ifadesindeki değerler, anahtar değeri ile aynı veri türünün derleme zamanı sabit değerleri olmalıdır.
aşağıdaki gibi bir şey (yerel örnek olarak yönteminizde veya sınıfınızda statik değişken olarak (o zaman statik ekleyin) veya bir örnek değişkeni bildirin.
final String color1 = "Red";
ve
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
Bir yerel değişken değil, bir sınıf / örnek değişkeni ise bu kod derlenmeyecektir . Bu derleme olacak color1
statik nihai (o zaman statik nihai değişken haline gelir) olarak tanımlanır.
Derlenmediğinde, aşağıdaki hatayı alırsınız
error: constant string expression required
"const" anahtar kelimesi, değişkeninizin ROM'a (Mikroişlemci ile) kaydedildiği anlamına gelir. bilgisayarda, değişkeniniz Montaj kodu için RAM alanına kaydedilir (salt okunur RAM). değişkeninizin yazılabilir RAM'de olmadığı anlamına gelir: statik bellek, yığın bellek ve yığın bellek.
"final" anahtar kelimesi, değişkeninizin yazılabilir RAM'e kaydedildiği anlamına gelir, ancak derleyicinizin değişkeninizin yalnızca bir kez değiştiğini fark edersiniz.
//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" performansının kötü olduğunu düşünüyorum, bu yüzden Java bunu kullanmaz.