2015-12-11 30 views
9
Sadece ben sadece bir const referans değişkeni izin eğer insanlar hiç bunu yapmak görünmüyor neden acaba

Getter işlevleri yerine const başvurularını kullanabilir miyim?

#include <string> 

class cTest 
{ 
    private: 
     int m_i; 
     std::string m_str; 

    public: 
     const int & i; 
     const std::string & str; 

    cTest(void) 
    : i(m_i) 
    , str(m_str) 
    {} 
}; 

int main(int argc, char *argv[]) 
{ 
    cTest o; 
    int i = o.i; // works 
    o.i += 5; // fails 
    o.str.clear(); // fails 

    return 0; 
} 

şöyle ben, alıcılar kullanarak atlatabilir merak

. Kaybettiğim ciddi dezavantaj var mı? Lütfen avantaj ve dezavantajlar listesine katkıda bulunun ve gerekirse bunları düzeltin.

Avantajları: alıcı fonksiyonlarının çağrıları yoluyla hiçbir havai yoktur

  1. .
  2. Program boyutu küçülüyor çünkü daha az işlev var.
  3. Sınıfın içeriklerini hala değiştirebilirim, referans değişkenleri bir soyutlama katmanı sağlar.

Dezavantajları:

  1. yerine alıcı fonksiyonları, ben referansların bir grup var. Bu nesne boyutunu artırır.
  2. const_cast'u kullanarak, kullanıcılar özel üyeleri dağıtabilir, ancak bu insanlar yaramaz değil mi?

    1) tedarik (ve dolayısıyla sürdürmeniz gerekir) a: gerçekten de (bir kenara da ben de "ağır" kategorisinde koymak hangi söz 2 dezavantajın)

cevap

7

Bazı şiddetli dezavantajları kopya kurucu: derleyici varsayılan çalışmaz.

2) Bir atama işleci sağlamanız gerekir: derleyici varsayılan olarak çalışmaz.

3) Hareket semantiğinin uygulanmasına dikkatlice düşünün. Yine, derleyici varsayılan çalışmaz.

Bu üç şey, başlattığınız const referans anti-pattern'in marş olmamasıdır. Yapma!

+5

Veriler için daha verimli bir gösterim kullanmak istediğinizde gün söz konusu değildir ve bu türlere geçerli bir başvuruma gereksiniminiz olduğundan bunu yapamazsınız. – chris

+0

@chris: Bu iyi bir nokta. Bir yapılandırma hatası döndüren bir işleviniz olsa bile, veri modelinizin değişmesi durumunda bir değer kopyasının döndürülmesi için bunu her zaman yeniden düzenleyebilirsiniz. – Bathsheba

2

Getter işlevlerinden bir avantajı, belirli bir zamanda - döndürülmüş değeri değiştirmek isteyebilirsiniz - ve getter işlevi olmadan bunu yapamazsınız. Bu senaryo aslında C++ 'da daha az yaygın olan referans dışı döndürmenizi gerektirir. [değiştir] ancak referanslar yerine hareket semantiği ile bu yapılmalıdır [/ edit]

Ayrıca, değeri kimin okuduğunu öğrenmek için kayıt işlevine bir kesme noktası koymak isteyebilirsiniz, günlük kaydı eklemek isteyebilirsiniz. Buna kapsülleme denir.

Getterin diğer avantajı, hata ayıklama yapısında, döndürülen verilerde ek kontroller/ekler ekleyebileceğinizdir.

Son derleyici, getter işlevlerinizi satır içinde gösterecek ve bu da teklif ettiğinizle aynı kodla sonuçlanacaktır.

bazı ek dezavantaj:

1) şablon kodu işlev çağrısı, yani kullanarak değerleri almak isteyecektir. size(), const & değişkenine değiştirirseniz, bazı şablonlarda kullanamazsınız. Yani bu bir tutarlılık problemidir.

0

Alıcılar ve ayarlayıcılardan kaçınmak istiyorsanız, bir yapı referansı üyesi kullanmak çözüm değildir. Bunun yerine, çevre yapısında (üyelere otomatik olarak erişim izni veren) yapının doğruluğunu sağlamak ve üyelerin mantıksal olarak ihtiyaç duydukları her şeye izin vermesini sağlamak istersiniz.

Alıcılar ve ayarlayıcılar, herkese açık veri üyeleriyle açılabilir veya değiştirilebildiği zaman okumaya dikkat edin. Bakınız örn. this question. Arayüzünüzü değiştirirseniz, setters/getters'ın müjdeli dvantage'ının, geticiyi çağırmanın çağrı sitelerini etkilemeyeceğini unutmayın. Gerçeklik aksi iddia edilir gibi görünüyor ve ör. Bir üyeyi tüm erişim noktaları ile birlikte yeniden düzenlemek, kendinize saygı duyan C++ kod editörü için önemsiz bir işlemdir. Bir kapsülleme için tartışabilir olsa da, daha fazla kapsülleme ihtiyacını azaltan ve kodu gerçekten çok basitleştiren const doğruluğu konusunda daha fazla tartışmak isterim.