const int* const Method3(const int* const&) const;
Birisi sabitlerin her birinin kullanımını açıklayabilir mi?
Yanıtlar:
Bunu okuyun: https://isocpp.org/wiki/faq/const-correctness
Son const
, işlevin Method3
sınıfının değişken olmayan üyelerini değiştirmediği anlamına gelir .
const int* const
sabit bir int için sabit bir işaretçi anlamına gelir: yani değiştirilemeyen bir işaretçi, değiştirilemeyen bir int için: bununla arasındaki tek fark const int&
şu olabilirnull
const int* const&
sabit bir int için sabit bir göstericiye bir başvuru anlamına gelir. Genellikle işaretçiler referans olarak aktarılmaz; const int* &
daha mantıklıdır çünkü bu, göstericinin yöntem çağrısı sırasında değiştirilebileceği anlamına gelir; bu, bir göstericiyi referans olarak geçirmeyi görebilmemin tek nedeni , muhtemelen daha az verimli olması dışında const int* const&
tüm amaç ve amaçlarla aynıdır. const int* const
işaretçiler düz eski veri (POD) türleridir ve bunlar genellikle değere göre aktarılmalıdır.
Bunu tamamen eşdeğer olarak yazarsanız anlamak daha kolay
// v───v───v───v───v───v───v───v───v───v───v───v─┬┐
// ││
// v──#1 v─#2 v──#3 v─#4 #5
int const * const Method3(int const * const&) const;
sonra sağdan sola doğru okuyun.
# 5, soldaki tüm işlev bildiriminin olduğunu söylüyor const
, bu da bunun özgür bir işlevden ziyade zorunlu bir üye işlev olduğunu ima ediyor.
# 4, soldaki işaretçinin const
(farklı bir adresi gösterecek şekilde değiştirilemeyebilir) olduğunu söylüyor .
# 3 int
, soldan const
(farklı bir değere sahip olacak şekilde değiştirilemez) diyor .
# 2, soldaki işaretçinin olduğunu söylüyor const
.
# 1 int
, soldan olduğunu söylüyor const
.
Hepsini bir araya koyarsak, bunu bir göstericiye (veya tercih ederseniz a) bir göstericiye başvuran ve ( ) ' ye bir işaretçi döndüren const
adlı bir üye işlev olarak okuyabilirsiniz .Method3
const
int const
const int
const
int const
const int
(Not # 2 tamamen gereksizdir .)
Öncelikle const T
eşdeğerdir T const
.
const int* const
bu nedenle eşdeğerdir int const * const
.
const
İçinde çok sayıda simge ve işaret bulunan ifadeleri okurken , bunları her zaman sağdan sola doğru okumaya çalışın (yukarıdaki dönüşümü uyguladıktan sonra). Bu durumda, dönüş değeri bir constint
için bir const göstericisidir . const
Dönüş değeri değiştirilebilecek bir değer olmadığı için göstericinin kendisini yapmak burada bir anlam ifade etmiyor. Pointee yapmak const
, ancak, arayanın tarafından döndürülen int
(veya dizileri int
) değiştiremeyeceğini garanti eder Method3
.
const int*const&
olur int const*const&
, bu nedenle bu, bir const'a yönelik bir const işaretçisine başvurudurint
. Bir const işaretçisini erkek const
referanslarıyla geçirmek de anlamsızdır - işaretçi olduğundan ve referanslar ve işaretçiler eşit depolama alanı kapladığından , başvurulan değeri değiştiremezsiniz, böylece yer tasarrufu da olmaz.
Sonuncusu const
, yöntemin this
nesneyi değiştirmediğini gösterir. this
Yöntem gövdesinin içindeki işaretçi (teorik) beyanı olacaktır T const * const this
. Bu, bir const T*
nesnenin arayabileceği anlamına gelir T::Method3()
.
const
. İşte tam da bu yüzden const
, dil izin verse de oraya koymanın kötü bir uygulama olduğunu düşünüyorum ve en yaygın kullanım budur.
Kurallarını hatırlamanın kolay bir yolu, const
onu şu şekilde düşünmektir: const
solunda hiçbir şey yoksa, solundaki şey için geçerlidir.
Bu durumda const int * const
, birinci sabitin solunda hiçbir şey yoktur, bu nedenle geçerli olur int
ve ikincinin solunda bir şey vardır, bu nedenle işaretçiye uygulanır.
Bu kural, sahip olduğunuz durumda ne olacağını da söyler const int const *
. Her iki sabit de int
bu ifade için geçerli olduğundan gereksiz ve dolayısıyla geçersizdir.
const /* don't modify the int or array of ints' value(s) */
int* const /* as a retval, ignored. useless declaration */
Method3(const /* don't modify the int or array of ints' value(s) */
int* const /* don't modify the pointer's value, the address to which `pointer` points to. e.g. you cannot say `++pointer` */
&) const; /* this method does not modify the instance/object which implements the method */
Tanımlayıcı adından başlayarak (bu durumda ) şifresini çözmek için soldan sağa, geri sola vb. Okuduğunuz "saat" veya "spiral" yöntemini kullanmayı seviyorum. Method3
adlandırma kuralları. Yani const int* const Method3(const int* const&) const
, herhangi bir sınıf üyesini (adlandırılmamış bir sınıfın) değiştirmeyen ve bir sabiti işaret eden int
ve bir sabite sabit bir işaretçi döndüren bir işaretçiye sabit bir referans alan bir sınıf yöntemi int
.
Bu yardımcı olur umarım,
Jason
C ++ 'daki const'ı hatırlamanın kolay bir yolu, aşağıdaki gibi bir kod gördüğünüz zamandır:
XXX const;
const YYY;
XXX, YYY sabit bir bileşen olacaktır
XXX const
:
function ( def var ) const; ------#1
* const; ------#2
const YYY
form:
const int; ------#3
const double;
İnsanlar genellikle bu türleri kullanır. Bir yeri gördüğünüzde "const&"
, kafanız karışmasın, const kendisinden önce bir şeyi açıklıyor. bu yüzden bu sorunun cevabı şimdi apaçık ortada.
const int* const Method3(const int* const&) const;
| | | | |
#3 #2 #3 #2 #1
Ben sadece const int* const&
bunun gerçekten daimi bir referans olduğunu belirtmek istiyorum const int*
. Örneğin:
int i = 0;
int j = 1;
int* p = &i;
int* q = &j;
const int* const& cpref = p;
cpref = q; //Error: assignment of read-only reference 'cpref'
Bu aynı zamanda şu int* const&
anlama gelir: "Sürekli bir referans int*
".
Ama const int*&
sürekli olmayan bir referanstır const int*
.
Bu yardımcı olur umarım.
Sağdan sola okumak, değiştiricilerin anlaşılmasını kolaylaştırır.
Const bir int adında Method3
bir const işaretçisine bir const işaretçisini döndüren bir const yöntemi.
mutable
)const # 1: Method3 tarafından döndürülen işaretçi bir const int'e başvuruyor.
const # 2: İşlevin kendisi tarafından döndürülen işaretçi değeri sabittir. Bu işe yaramaz bir sabittir (dilbilgisi açısından geçerli olsa da), çünkü bir işlevin dönüş değeri bir l-değeri olamaz.
const # 3: İşleve başvurularak iletilen işaretçi türü bir const int'i işaret eder.
const # 4: İşleve referansla iletilen işaretçi değeri, kendisi bir const göstericisidir. Const olarak bir işleve aktarılan bir değeri bildirmek normalde anlamsız olacaktır, ancak bu değer referansla iletilir, bu nedenle anlamlı olabilir.
const # 5: İşlev (muhtemelen bir üye işlev) const'dir, yani (a) parçası olduğu nesnenin herhangi bir üyesine yeni değerler atamasına veya (b) const olmayan bir üye işlevini çağırmasına izin verilmez. nesnede veya üyelerinden herhangi birinde.
const
yöntemin sonunda, nesnenin durumunun değişmeyeceğini belirten niteleyici bulunur.
const int*const&
bir const konumuna bir const işaretçisine başvurarak almayı belirtir. Farklı bir konuma işaret etmek için değişemez veya işaret ettiği değeri değiştiremez.
const int*const
aynı zamanda sabit bir konuma sabit bir işaretçi olan dönüş değeridir.
Bu kavramı göstermek için birkaç örnek güzel olabilir, daha iyi imho.
class TestClass
{
private:
int iValue;
int* oValuePtr;
int& oValueRef;
public:
int TestClass::ByValMethod1(int Value)
{
// Value can be modified
Value++;
// iValue can be modified
iValue = Value;
iValue += 1;
// Return value can be modified
return ++iValue;
}
int TestClass::ByValMethod2(const int Value)
{
// Value *cannot* be modified
// Variable is const variable
Value++;
// iValue can be modified
iValue = Value;
iValue += 1;
// Return value can be modified
return ++iValue;
}
const int TestClass::ByValMethod3(int Value)
{
// Value can be modified
Value++;
// iValue can be modified
iValue = Value;
iValue += 1;
// Return value can be modified
return ++iValue;
}
const int TestClass::ByValMethod4(const int Value)
{
// Value *cannot* be modified
// Variable is const variable
Value++;
// iValue can be modified
iValue = Value;
iValue += 1;
// Return value can be modified
return ++iValue;
}
const int TestClass::ByValMethod5(const int Value) const
{
// Value *cannot* be modified
// Variable is const variable
Value++;
// iValue *cannot* be modified
// Access through a const object
iValue = Value;
iValue += 1;
// Return value *cannot* be modified
// Access through a const object
return ++iValue;
}
int& TestClass::ByRefMethod1(int& Value)
{
// Value can be modified
Value++;
// oValueRef can be modified
oValueRef = Value;
oValueRef += 1;
// Return value can be modified
return ++oValueRef;
}
int& TestClass::ByRefMethod2(const int& Value)
{
// Value *cannot* be modified
// Variable is const variable
Value++;
// oValueRef can be modified
oValueRef = Value;
oValueRef += 1;
// Return value can be modified
return ++oValueRef;
}
const int& TestClass::ByRefMethod3(int& Value)
{
// Value can be modified
Value++;
// oValueRef can be modified
oValueRef = Value;
oValueRef += 1;
// Return value can be modified
return ++oValueRef;
}
const int& TestClass::ByRefMethod4(const int& Value)
{
// Value *cannot* be modified
// Variable is const variable
Value++;
// oValueRef can be modified
oValueRef = Value;
oValueRef += 1;
// Return value can be modified
return ++oValueRef;
}
const int& TestClass::ByRefMethod5(const int& Value) const
{
// Value *cannot* be modified
// Variable is const variable
Value++;
// oValueRef can be modified
oValueRef = Value;
oValueRef += 1;
// Return value can be modified
return ++oValueRef;
}
int* TestClass::PointerMethod1(int* Value)
{
// Value can be modified
Value++;
// oValuePtr can be assigned
oValuePtr = Value;
// oValuePtr can be modified
oValuePtr += 1;
// Return value can be modified
return ++oValuePtr;
}
int* TestClass::PointerMethod2(const int* Value)
{
// Value can be modified
Value++;
// oValuePtr cannot be assigned
// const int* to int*
oValuePtr = Value;
// oValuePtr can be modified
oValuePtr += 1;
// Return value can be modified
return ++oValuePtr;
}
const int* TestClass::PointerMethod3(int* Value)
{
// Value can be modified
Value++;
// oValuePtr can be assigned
oValuePtr = Value;
// iValue can be modified
oValuePtr += 1;
// Return value can be modified
return ++oValuePtr;
}
const int* TestClass::PointerMethod4(const int* Value)
{
// Value cannot be modified
Value++;
// oValuePtr *cannot* be assigned
// const int* to int*
oValuePtr = Value;
// oValuePtr can be modified
oValuePtr += 1;
// Return value can be modified
return ++oValuePtr;
}
const int* TestClass::PointerMethod5(const int* Value) const
{
// Value can be modified
++Value;
// oValuePtr *cannot* be assigned
// const int* to int* const
// Access through a const object
oValuePtr = Value;
// oValuePtr *cannot* be modified
// Access through a const object
oValuePtr += 1;
// Return value *cannot* be modified
return ++oValuePtr;
}
};
Umarım bu yardımcı olur!