2015-08-05 12 views
5

Sabit bir argüman ve bu nesnenin içinde bir işaretçi değişkeni ile C++'da bir işlev yazdığımda, const bayrağının altta yatan belleğin değişikliklere karşı korunmadığını anlamaya çalışıyorum. Örneğin o X denilen sınıfın operator=() işlevinde aşağıdakileri yapmanız derece yasal:C++ 'da sabit bir nesnenin işaretçi üye değişkeninin belleğini dışarıdan neden değiştirmesine izin verilir?

class X 
{ 
public: 
    X& operator=(const X& other) 
    { 
     this->data = other.data; //(*) 
     return *this; 
    } 

private: 
    int* data; 
}; 

(*):

int* some_pointer; 
int* const other_pointer = some_pointer; 
int* class_pointer = other_pointer; 

Ama aynı değildir: Bu aşağıdaki aynıdır olarak:

: aşağıdaki hatası oluşturuyor

const int* other_pointer; 
int* class_pointer = other_pointer; 

other.x bir int* const için dökme ediliyor ancak (a const int* const olan) aynı anda bir const* int için dökme değil neden görmüyorum neden

error: invalid conversion from 'const int*' to 'int*' [-fpermissive] 
int* class_pointer = other_pointer; 
        ^

anlıyorum. const argümanı ile bir işlev yazdığımda mantığım, bu argümanın içerisindeki herhangi bir şeyi, kalıtsal veriyi modifikasyona karşı korumak için const'un amacı olmalıdır, çünkü bu argümanın içinde herhangi bir şey kalmasını önerir. Bir işaretçi üyesi bir sınıfın const versiyonunun dışından erişildiğini

Ben modifikasyon gelen sınıfın çıkar nesnenin const anahtar kelime herhangi bir şey (hatta bellek) korumalıyız dair makul bir beklenti olması gerektiğini düşünüyorum. Buna karşı olan argüman, dış belleğin nesneye ait olmaması ve dolayısıyla onu korumak için sorumluluk almamasıdır. Benim bu konudaki perspektifim, bu durumda (herhangi bir erişim hakkıyla başka bir yere erişilebildiği diğer durumların dışında) bir const nesnesinden bir şey çıkarmamızdır. Başka bir deyişle, kendi dışındaki bir şeye görünürlük kazandırır. Peki görünürlük const yapmamanın sebebi nedir? Bu, belleğin erişilebilirlik haklarını kodun başka herhangi bir yerinde değiştiremez!

const int* other_pointer 
declare other_pointer as pointer to const int 

nezaket

http://cdecl.org/ nolu dipnotta const yerleştirme farkı: aksine

+2

Burada ne sorduğundan emin değilim. Netleşmek ister misiniz? – juanchopanza

+1

Neden other.data (X :: operatörü =() işlevinde) int * const yerine const int * const dosyasına dökülmediğini ve C++ uygulamasının arkasında yatan tasarım kararının niçin olduğunu soruyorum. – Kristof01

+0

Çünkü bu bir anlam ifade etmiyor. – juanchopanza

cevap

0
int* const other_pointer 
declare other_pointer as const pointer to int 

.

+1

OP bunun farkında gibi görünüyor. – Quentin

4

"When I write a function with a const argument my logic suggests anything inside that argument should inherit the constness because that should be the purpose of const, to protect the underlying data against modification."

Sen X -Nesne noktaları dışında nesne içinde saklanır ancak işaretçi bu konuda çok haklısın. Dış X 's kabızlık, sadece X içinde saklanan veriler tarafından etkilenmez.

+0

Tamamen aynı fikirdeyim ama X'in X ve X'teki her şeyi değiştirilemeyen bir şey olarak gerçekten ele alması durumunda X'in bu "dış" belleğe sürekli bir görünürlük sağlama yükümlülüğü olması gerekir. Bu dış belleği hiç etkilemez! – Kristof01

+1

Sanırım "dış" verilerin mevcut sınıf tarafından * ait olup olmadığına bakılıyor. Eğer evet ise, o zaman gerçekten dışarıdan veri değildir. Belki de OP'nin asıl sorusu, "neden üye olmayanların * sahip olunan verilere * ve dolayısıyla 'const'-propogating'e işaretçi olmadıklarını" düşünmektedir. –

+0

... (devam) C++ 'da,' const 'yöntemleri içinde üyelerin değişmesine izin vermek için' mutable 'anahtar sözcüğüne zaten sahibiz - buradaki değişiklikler, bu değişikliklerin' mantıksal 'yapısını değiştirmeyeceği yönündedir. metodlar. Bu yüzden belki de işaretçiler varsayılan olarak const'-propogating olmalıydı, ancak gerektiğinde değiştirmek için 'değişebilir' ile (sahip olmadıkları dahil). * (Tabii ki, biz yaklaşık 30 yıl geç bunu yapmak için çok geç!) * –

0

other.data değerini değiştirmiyorsunuz, dolayısıyla const ihlali söz konusu değil. other.data'un işaret ettiği nesneyi kesinlikle değiştirebilirdiniz, ancak bu, kabinin doğruluğunu zorlamak için derleyicinin sorumluluğundadır.

1

Neden bunu düşünüyorsunuz, çünkü işaretçi sabit, işaret edilen nokta sabit olmalı? Mutlaka takip edilmez.

Bazen her zaman belirli bir yere işaret etmesi gereken, ancak belirtilen yeri değiştirebileceğiniz bir işaretçiye ihtiyacınız vardır. class X ile ilgili hiçbir şey yoktur, bu da data puanını değiştirememenizi önerir.

Daha da önemlisi, const anahtar sözcüğü hakkında yanlış düşünmüyorsunuz.

X& operator=(const X& other) 

Verilen size operator=() içine other değiştirmek niyetinde değilim derleyici anlatmak ve de unutulma ihtimaline karşı bunu yaparken engellemek için derleyici istiyor yapıyoruz bütün. Ne fazla ne eksik. Bu, operator=()'un dışındaki other'un yapısı ile ilgili hiçbir şey ya da other'un içinde herhangi bir işaretçinin işaretiyle ilgili hiçbir şey söylemez.