Özel üyeleri neden başlıklara koymalıyız?


62

Özel değişkenler, karmaşıklığı ve uygulama ayrıntılarını bir sınıf kullanıcısına gizlemenin bir yoludur. Bu oldukça hoş bir özellik. Fakat neden c ++ 'ta onları bir sınıf başlığına koymamız gerektiğini anlamıyorum. Bunun için iki sinir bozucu dezavantaj görüyorum:

  • Başlığı kullanıcıdan alır.
  • İçindekiler değiştirildiğinde, tüm istemci kitaplıklarının yeniden derlenmesini zorlar.

Bu gereksinimin arkasında kavramsal bir sebep var mı? Sadece derleyiciden çalışmayı kolaylaştırmak için mi?


Eğer başlığında bir boş yapı bildirmek olabilir ama o zaman sadece Eğer kullandığınız zaman böyle bir yapı için işaretçileri kullanabilir (ve tek ayrılamıyor)
ucube mandalınızı

3
@ratchetfreak: Hayır, boş ( struct foo{};) izin verilmiyor, ancak ileriye dönük bildirimler ( struct foo;) kullanılıyor.
MSalters

@ MSalters demek istediğim bu
cırcır ucube

1
Bir dezavantaj ekleyeyim: * .h dosyasına özel fonksiyon başlıklarını yazmak çok zaman kaybı. (bir süreliğine arkadaş sınıflarını unutmak)
Jonny,

Yanıtlar:


68

Bunun nedeni, C ++ derleyicisinin, başlatma sırasında doğru miktarda bellek tahsis etmek için sınıfın gerçek boyutunu bilmesi gerektiğidir. Ve büyüklüğü tüm üyeler, aynı zamanda özel üyeler içerir.

Bundan kaçınmanın bir yolu , Herb Sutter tarafından Haftanın Guru dizisi # 24 ve # 28'de açıklanan Pimpl deyimini kullanmaktır .

Güncelleme

Nitekim, bu (veya daha genel olarak, başlık / kaynak dosya ayrım ve #includeler) gün içerisinde C. Geri miras C ++, içinde büyük bir engel olduğunu C ++ C yaratıldı, büyük ölçekli yazılım geliştirme ile ilgili deneyim nerede bu, henüz yoktu gerçek sorunlara neden olmaya başlar. O zamandan beri öğrenilen dersler, yeni dil tasarımcıları tarafından dikkate alındı, ancak C ++, dilde böylesine temel bir konuyu ele almayı gerçekten zorlaştıran geriye dönük uyumluluk gerekliliklerine bağlı kaldı.


Bu tür bilgiler sadece sınıf kütüphanesinde yer almıyor mu? Bağlantı için kullanılıyor mu?
Simon Bergot

@Simon, "sınıf kütüphanesi" ile ne demek istiyorsun?
Péter Török

Sınıf tanımını ve yöntemlerini içeren nesne dosyalarının toplanmasını kastediyorum
Simon Bergot

7
C ++ yaratıldığında, AT & T / Bell Laboratuarları (o zamandaki Stroustrups işveren) kesinlikle büyük ölçekli C geliştirme konusunda deneyime sahipti. Onların 5ESS telefon değiştirme yazılımı, o zamanlar muhtemelen dünyadaki en büyük tek C programıydı. OO hakkındaki ilk fikirler zaten bu kod tabanında görülebilir ve Cfront bu teknikleri taklit etti. Ancak, kavramı privatedaha moderndir.
MSalters

1
C'de, tahsisatçıyı bir kütüphane fonksiyonuna koymanız yeterlidir; müşteri böyle bir yapıyı hiçbir şekilde tahsis edemezdi. Bu, ek yükü biraz artırır, ancak kodun önemsiz sürümler arasında geçişini sağlar, bu nedenle genellikle faydalı olur. Bununla birlikte, C ++ 'da görünenden çok farklı bir kod stiline yol açma eğilimindedir.
Donal Fellows,

15

Sınıf tanımının, derleyicinin sınıfın bir nesnesini kullandığınız her yerde bellekte özdeş bir düzen oluşturması için yeterli olması gerekir. Örneğin, şöyle bir şey verilir:

class X { 
    int a;
public:
    int b;
};

Derleyici tipik olarak a0 ofsetinde ve bofsette olacaktır 4. Derleyici bunu sadece şöyle görmüşse:

class X { 
public:
    int b;
};

Bu b, ofset 4 yerine 0 ofsetinde olması gerektiğini "düşünür". Bu tanımı kullanan kod atandığında b, ilk tanımı kullanan kodun adeğiştirildiğini göreceksiniz ve bunun tersi de geçerlidir.

Sınıfın özel bölümlerinde değişiklik yapmanın etkilerini en aza indirmenin genel yolu genellikle pimpl deyimidir (Google’ın çok fazla bilgi verebileceğinden eminim).


1
Bir tasarım kararı hakkında soruyorum. Tabii ki, özel üye bildirimini dilin çalışması için bir yere koymanız gerekir. Peki neden daha özel bir yerde değil de başlıkta olsun?
Simon Bergot

7
@Simon: Başlık, derleyicinin sınıf / yapı nasıl göründüğünü söylemek için gördüğü şeydir. C ++ 'a modüller gibi bir şey ekleme tartışmaları yapıldı, bu tür verileri biraz daha gizleyecekti, ancak şu ana kadar onaylanmadı (ya da tamamen düşürülmese de).
Jerry Coffin

3
Yine de, önemsiz bir kural, bu gibi ".cpp tanımlı" özel üyelere en son tahsisat yapmak olacaktır. Bu, halkın ve "normal" özel üyelerin uzaklıkları onlara bağlı olmayacağı anlamına gelir. IMO'nun asıl nedeni, böyle bir sınıftan miras alamazsınız, çünkü türetilmiş kısım bu özel üyeleri bile takip etmek zorunda.
MSalters

3

Büyük olasılıkla birkaç nedeni vardır. Özel üyelere diğer sınıfların çoğu tarafından erişilemezken, yine de arkadaş sınıfları tarafından erişilebilir. Yani en azından bu durumda başlığa ihtiyaç duyulabilir, böylece arkadaş sınıfı varlığını görebilir.

Bağımlı dosyaların yeniden derlenmesi, include yapınıza bağlı olabilir. .H dosyalarının başka bir başlık yerine bir .cpp dosyasına dahil edilmesi, bazı durumlarda uzun derleme zincirlerini engelleyebilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.