isteğe bağlı olmayan işaretçiler ve C ++ 'da const olmayan başvurular


12

Gelen Diğer C ++ Özellikleri, Referans Argümanlar ait tarihinde C ++ Stil Rehberi , bunu const olmayan referanslar kullanılmamalıdır okuyun.

Referansla iletilen tüm parametreler sabit olarak etiketlenmelidir.

Başvuruları argüman olarak kullanan işlev çağrılarına bakmanın C programcıları için kesinlikle kafa karıştırıcı olduğu açıktır, ancak C ve C ++ artık farklı dillerdir. Bir çıkış parametresi gerekiyorsa , gerekli bir çıkış parametresi için bir işaretçi kullanılması, tüm işlev gövdesinin atlanmasına neden olabilir, bu da bir işlevin uygulanmasını daha karmaşık hale getirir (bir işlevin siklomatik karmaşıklığını ve derinliğini resmi olarak artırır ).

Mümkün olduğunca kolay anlamak / korumak için C ++ kodu yapmak istiyorum, bu yüzden genellikle kodlama tarzı kılavuzları okumak ilgimi çekiyor. Ancak bir takımdaki en iyi uygulamaları uyarlayabilmek için, stil rehberi öğelerinin arkasındaki mantığı anlamanın önemli bir faktör olduğunu düşünüyorum.

Sabit olmayan referanslar gerçekten bu kadar kötü mü? Yasakları yalnızca Google'a özgü mü yoksa yaygın olarak kabul edilen bir kural mı? Çıktı parametrelerini işaretçi olarak uygulamaya yönelik ekstra çabayı haklı kılan nedir?


2
"bunun için bir işaretçi kullanarak tüm işlev gövdesi atlanmasına neden olur", ne?
cırcır ucube

@ratchetfreak Bunu açıklamaya çalıştım. Bunun gibi işlevlerin bazı tasarım kusurları gösterebileceğini itiraf ediyorum. Bir işaretçi her zaman resmi olarak isteğe bağlıdır, bu nedenle kayıttan çıkarılmadan önce kontrol edilmesi gerekir.
Wolf

4
Google'ın C ++ stil kılavuzu oldukça geri. Benim öznel görüşüme göre, yakılmalıdır.
Siyuan Ren

Bu özel maddeye gelince, mantığın, argümanların mutasyona uğratılabileceği programcıları bir ve işareti yazmaya zorlamanın daha açık bir niyet gösterdiğini düşünüyorum.
Siyuan Ren

4
Google Stil Kılavuzu, eski Google projelerinde homojen kodu desteklemek için olduğu gibi yazılmıştır. Eski projeler üzerinde çalışmıyorsanız (bu stil kılavuzuyla baştan yazılmıştır), muhtemelen kullanmamalısınız (yeni kod için iyi olmayan birçok kuralı belirtir (c ++ 11, c ++ 14) , c ++ 17)).
utnapistim

Yanıtlar:


18

Google'ın stil kılavuzunun arkasındaki mantık, bir parametrenin bir giriş parametresi mi yoksa bir çıkış parametresi mi olduğunu bir işlevin çağrı sitesinden açıkça belirtmektir. (Daha fazla tartışma için buraya bakın .) Diğer diller tasarım gereği parametreleri açıkça ortaya koyar; Örneğin C #, çağrı sitesinde kullanılması gereken bir outanahtar kelimeye sahiptir . C ++ bunu açıkça belirtmediği için Google const ref kullanmayı seçti. işaretçi ile işaretleyin.

Bu sadece bir Google kuralı mı? Hayır, ama çok yaygın olduğundan şüpheliyim. Bunu Google'ın stil kılavuzunun ve Google stil kılavuzunun bazı bölümlerine açıkça bağlı olan grupların dışında gördüğümü sanmıyorum. (Örneğin, yıllar önce Google stil kılavuzunu okuduğumda ve kendi kodumdan bazıları için kullandığımda fikri beğendim.)

Özellikle, yeni duyurulan C ++ Temel Yönergeleri , (neredeyse) her şeyin çıktı parametrelerine dönüş değerlerini tercih eder ve geri kalanı için const olmayan ref'leri kullanır. Google'ın işaretçileri referanslara karşı kullanımı çıktı parametrelerini daha net hale getirebilir, ancak dönüş değerleri daha net olur. Artık C ++ 11'in standartlaştırılmış hamleleri ( &&birçok türün geri dönüşünü ucuza yapmak için rvalue referansları ) ve tuples (birden fazla değer döndürmek için kolay bir yol sağlar), artık out parametreleri için kullanım durumlarının çoğu artık geçerli değildir.

C ++ Temel Yönergeleri'nin arkasında bazı büyük isimler (Bjarne Stroustrup, Herb Sutter) var, Microsoft tarafından destekleniyor ve en yeni C ++ özelliklerini (Google'ın stil rehberinden farklı olarak) kucaklıyorum, bu yüzden önerilerinin Google'dan daha popüler olmasını bekliyorum.


Cevabınız için teşekkürler (ayrıca C #'a kısa bir gezi için). Kolay inceleme, özellikle Açık Kaynak projelerinde önemli bir noktadır. Modern C ++ 'da ucuz getiri ile bu düşünceler önemini yitirecektir. Eski eski yazılımlar ve eski derleyicilerle yine de yardımcı olabilir.
Kurt

Bunu unutmadım, ancak C ++ Temel Yönergeleri almak o kadar hızlı değil. O bu kadar çok ilginç Felsefe kurallarına arkasındaki mantık ve ayrıca programlama üzerine modernize görünüm iletişim kurmak için bir yol olarak ( "kod doğrudan Ekspres fikirleri" pitonun Zen gibi biraz okur) gösterileri.
Kurt

Ek: C ++ Kod Yönergeleri'nin Felsefe bölümüne doğrudan bağlantı .
Wolf

1

Geçersiz bir işaretçi ile uğraşmak için 2 seçenek vardır, önce kontrol edin ve erken dönün veya tanımlanmamış davranış olmasına izin verin (hızdan daha fazla sağlamlık istiyorsanız).

Kontrol etmek şu kadar basit:

void foo(void* buffer){
    if(buffer == nullptr)
        return;

    //actually foo

    // note no increase in indentation required

}

Bu tür bir kontrol genellikle bir parametre kontrolü olarak kabul edilir. Kodu görürseniz, boş olmayan bir işaretçinin geçmesini ve eğer değilse erken dönmesini beklediğiniz oldukça açıktır. Bu, geçersiz işaretçiler hakkında fazla endişelenmenize izin vermez.


Bu modeli düşündüm ve kesinlikle makul buldum. Ne yazık ki bu assert(buffer);iddia sadece hata ayıklama sürümü için aktif olduğunu bilmek kadar net görünmüyor , bazen rt_assert(buffer);bir istisna atan bir sahip olmak istiyorum. returnGörünüşün girintisi biraz tehlikeli ... BTW: kod snippet'iniz çıktı için işaretçilerle ilgili sorumun iyi bir örneğidir.
Wolf

1

Gözleminize geliyor If an output parameter is required.

Çıktı parametresine sahip olmak için işlev imzasının gerekli olduğu tek yer, harici bir API tarafından belirtildiği zamandır ve bu durumda harici API'yi her zaman geçerli bir pointee olmasını sağlayan bir şeye sararsınız.

Dahili olarak, dönüş türünü tüm "çıkışların" bir bileşiği olacak şekilde genişleterek çıkış parametrelerinden kaçınırsınız


Yani, zorunlu olmayan bir işaretçi sağlayamadığım tek yer? Doğru, ancak kuralınızın The only place where...tüm durumlar için gerçekten geçerli olup olmadığından emin değilim . Önerdiğiniz gibi: kendi programlarınızın işlevlerinde çıkış parametrelerinden kaçının. Yeni programlar için geçerlidir.
Wolf

1
Evet, çıktı parametrelerinden kaçının, bileşik dönüş türlerini tercih edin, bunu daha net hale getirmek için düzenlenmiş
Caleth
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.