Bir sabit işaretçinin oldukça uygulanabilir olduğu bir örnek, bu şekilde gösterilebilir. İçinde dinamik bir dizi olan bir sınıfınız olduğunu ve kullanıcının diziye erişimini, ancak işaretçiyi değiştirme hakları vermeden geçirmek istediğinizi düşünün. Düşünmek:
#include <new>
#include <string.h>
class TestA
{
private:
char *Array;
public:
TestA(){Array = NULL; Array = new (std::nothrow) char[20]; if(Array != NULL){ strcpy(Array,"Input data"); } }
~TestA(){if(Array != NULL){ delete [] Array;} }
char * const GetArray(){ return Array; }
};
int main()
{
TestA Temp;
printf("%s\n",Temp.GetArray());
Temp.GetArray()[0] = ' '; //You can still modify the chars in the array, user has access
Temp.GetArray()[1] = ' ';
printf("%s\n",Temp.GetArray());
}
Hangi üretir:
Girdi verileri veri
koyma
Ama bunu denersek:
int main()
{
TestA Temp;
printf("%s\n",Temp.GetArray());
Temp.GetArray()[0] = ' ';
Temp.GetArray()[1] = ' ';
printf("%s\n",Temp.GetArray());
Temp.GetArray() = NULL; //Bwuahahahaa attempt to set it to null
}
Biz:
hata: atamanın sol işleneni olarak lvalue gerekli // Drat tekrar başarısız oldu!
Bu yüzden dizinin içeriğini değiştirebiliriz, ancak dizinin işaretçisini değiştiremeyiz. İşaretçiyi kullanıcıya geri gönderirken tutarlı bir duruma sahip olduğundan emin olmak istiyorsanız iyi. Ancak bir yakalama var:
int main()
{
TestA Temp;
printf("%s\n",Temp.GetArray());
Temp.GetArray()[0] = ' ';
Temp.GetArray()[1] = ' ';
printf("%s\n",Temp.GetArray());
delete [] Temp.GetArray(); //Bwuahaha this actually works!
}
İmlecin kendisini değiştiremesek bile işaretçinin bellek referansını silebiliriz.
Bu nedenle, bellek referansının her zaman bir şeye işaret etmesini istiyorsanız (IE, şu anda bir referansın nasıl çalıştığına benzer şekilde asla değiştirilmez), o zaman oldukça uygulanabilir. Kullanıcının tam erişime sahip olmasını ve üzerinde değişiklik yapmasını istiyorsanız, sabit olmayan sizin içindir.
Düzenle:
OkArz001 GetArray () bir sağ-değer işlenen olduğu için atama yapamadığına dair yorumda bulunduktan sonra, yorumu tamamen doğrudur, ancak işaretçiye bir referans döndürmeniz durumunda yukarıdakiler hala geçerlidir (GetArray'ın referans gönderme), örneğin:
class TestA
{
private:
char *Array;
public:
TestA(){Array = NULL; Array = new (std::nothrow) char[20]; if(Array != NULL){ strcpy(Array,"Input data"); } }
~TestA(){if(Array != NULL){ delete [] Array;} }
char * const &GetArray(){ return Array; } //Note & reference operator
char * &GetNonConstArray(){ return Array; } //Note non-const
};
int main()
{
TestA Temp;
Temp.GetArray() = NULL; //Returns error
Temp.GetNonConstArray() = NULL; //Returns no error
}
İlk hata ile sonuçlanır:
hata: salt okunur konumun atanması 'Temp.TestA :: GetArray ()'
Ancak ikincisi, altındaki potansiyel sonuçlara rağmen nadiren gerçekleşecek.
Açıkçası, 'neden bir işaretçiye bir referans döndürmek istersiniz' sorusu ortaya çıkacak? Doğrudan söz konusu orijinal işaretçiye bellek (veya veri) atamanız gereken nadir durumlar vardır (örneğin, kendi malloc / free veya new / free front-end'inizi oluşturmak), ancak bu durumlarda const olmayan bir referanstır . Bir const pointer bir referans onu garanti bir durum rastlamak değil (belki iade türleri yerine beyan const başvuru değişkenleri olarak?).
Bir sabit işaretçi alan bir işleve sahip olduğumuzu düşünün (buna karşı olmayan):
class TestA
{
private:
char *Array;
public:
TestA(){Array = NULL; Array = new (std::nothrow) char[20]; if(Array != NULL){ strcpy(Array,"Input data"); } }
~TestA(){if(Array != NULL){ delete [] Array;} }
char * const &GetArray(){ return Array; }
void ModifyArrayConst(char * const Data)
{
Data[1]; //This is okay, this refers to Data[1]
Data--; //Produces an error. Don't want to Decrement that.
printf("Const: %c\n",Data[1]);
}
void ModifyArrayNonConst(char * Data)
{
Data--; //Argh noo what are you doing?!
Data[1]; //This is actually the same as 'Data[0]' because it's relative to Data's position
printf("NonConst: %c\n",Data[1]);
}
};
int main()
{
TestA Temp;
Temp.ModifyArrayNonConst("ABCD");
Temp.ModifyArrayConst("ABCD");
}
Sabit hata böylece mesaj üretir:
hata: salt okunur parametrenin azalması 'Veri'
Bu, yorumlarda belirtilen sorunlara neden olmak istemedikçe, muhtemelen bunu yapmak istemediğimiz için iyidir. Const işlevindeki azalmayı düzenlersek, aşağıdakiler gerçekleşir:
NonConst: Bir Yapısı:
B
Açıkça, A 'Veri [1]' olsa da, 'Veri [0]' olarak kabul edilir, çünkü NonConst işaretçisi azaltma işlemine izin verir. Const uygulandığında, başka bir kişinin yazdığı gibi, potansiyel hatayı oluşmadan yakalarız.
Bir diğer ana husus, bir const işaretçisinin sözde referans olarak kullanılabilmesidir, referansın işaret edeceği şey değiştirilemez (bir mucize, belki de bu nasıl uygulandıysa). Düşünmek:
int main()
{
int A = 10;
int * const B = &A;
*B = 20; //This is permitted
printf("%d\n",A);
B = NULL; //This produces an error
}
Derlemeye çalışırken aşağıdaki hatayı üretir:
hata: salt okunur değişken 'B' ataması
A'ya sürekli bir referans isteniyorsa, muhtemelen kötü bir şeydir. Yorum yapılırsa B = NULL
, derleyici mutlu bir şekilde değiştirmemize izin verir *B
ve bu nedenle A. Ints ile kullanışlı görünmeyebilir, ancak geçebileceğiniz, atıfta bulunabilecek, değiştirilemeyen bir işaretçi istediğiniz tek bir grafik uygulamasının duruşu olup olmadığını düşünün. etrafında.
Kullanımı değişkendir (istenmeyen puntayı bahane edin), ancak doğru bir şekilde kullanıldığında, programlamaya yardımcı olmak için kutudaki başka bir araçtır.