Neden C ++ sınıflarında üye değişkenler üzerinde önekler kullanılır?


150

Birçok C ++ kodu üye değişkenleri işaretlemek için sözdizimsel kurallar kullanır. Yaygın örnekler şunları içerir:

  • m_ MemberName (kamu üyeler hiç kullanılmaktadır) Kamu üyeleri için
  • _ member Özel üyeler veya tüm üyeler için ad

Diğerleri> bu- kullanarak zorlamak için deneyin üyeyi üye değişkeni her kullanıldığında.

Deneyimlerime göre, en büyük kod tabanları bu tür kuralları tutarlı bir şekilde uygulamada başarısız olur.

Diğer dillerde, bu sözleşmeler çok daha az yaygındır. Sadece ara sıra Java veya C # kodunda görüyorum. Sanırım hiç Ruby veya Python kodunda görmedim. Bu nedenle, üye değişkenler için özel biçimlendirme kullanmama konusunda daha modern dillerle bir eğilim var gibi görünüyor.

Bu sözleşme bugün C ++ 'da hala faydalı mı yoksa sadece bir anakronizm mi? Özellikle kütüphanelerde tutarsız bir şekilde kullanıldığı için. Diğer diller üye önekleri olmadan yapılabileceğini göstermedi mi?


15
Onu tercih ederim; karmaşık kod tabanlarında, hangi değişkenlerin yerel hangilerinin yerel olmadığını bilmek önemli olabilir. Genelde bunu çok zorlamak için önek kullanıyorum -> çok fazladan yazım ve isteğe bağlı olduğunu görüyorum (oysa adlandırma bunu yapmaya zorlayacaktır)
Joe

5
Öznitelik için @ ve öznitelikleri doğrudan kullanmak yerine erişimci oluşturma deyimi nedeniyle bunu Ruby'de hiç görmediniz.
Steve Jessop

6
PEP 8'e göre halka açık olmayan üye değişkenlere Python'da bir alt çizgi eklenmelidir (örnek:) self._something = 1.
Nathan Osman

2
Bunları tanımlamak için editörün sözdizimi vurgulaması kullanılmamalıdır mı?
Çok

2
this->memberPython kodunda eşdeğerini gördünüz . Python'da tipik olarak olurdu self.memberve sadece bir sözleşme değildir, dil tarafından gereklidir.
matec

Yanıtlar:


48

Öncelikli bir alt çizgi kullanmaya dikkat etmelisiniz. Bir kelimedeki büyük harflerden önce bir alt çizgi ayrılmıştır. Örneğin:

_Foo

_L

hepsi ayrılmış kelimeler iken

_foo

_l

değiller. Küçük harflerden önce alt çizgilere izin verilmeyen başka durumlar da vardır. Benim özel durumumda, _L Visual C ++ 2005 tarafından ayrılmış olduğunu buldum ve çatışma beklenmedik bazı sonuçlar yarattı.

Yerel değişkenleri işaretlemenin ne kadar yararlı olduğu konusunda kararsızım.

Hangi tanımlayıcıların ayrılmış olduğu hakkında bir bağlantı: Bir C ++ tanımlayıcısında alt çizgi kullanma ile ilgili kurallar nelerdir?


4
Aslında, hem _foo hem de _l, ad alanı kapsamında saklıdır.

13
Ancak üye değişken adları olarak uygundurlar. Alt çizgileri önek olarak eklemiyorum, çünkü kurallar çok kafa karıştırıcı ve geçmişte yanmıştım.
Juan

11
Bunlar ayrılmış kelimeler değil. Ayrılmış isimlerdir. Ayrılmış kelimeler olsaydı, onları hiç kullanamazdınız. Ayrılmış adlar oldukları için bunları kullanabilirsiniz, ancak kendi sorumluluğunuzdadır.
TonyK

235

Hepsi iyi yapılmış öneklerden yanayım .

Bence (Sistem) Macar notasyonu, öneklerin aldığı "kötü rap" in çoğundan sorumludur.

Bu gösterim, büyük ölçüde yazılan dillerde (örneğin C ++ "lpsz"), dizenizin boş bir sonlandırılmış dizeye uzun bir işaretçi olduğunu söylemek için büyük ölçüde anlamsızdır: char dizileri ve "customerName" bir dize olduğunu bilmek o kadar da zor değil!

Ancak, Sistem Macarca ile kötü ve haksız bir ilişkisi olması nedeniyle Macarca terimden kaçınmayı tercih etsem de , bir değişkenin (esas olarak "Apps Macarca" kullanımını belirtmek için önekleri kullanıyorum ve bu çok kullanışlı bir zaman tasarrufu ve hata azaltıcı yaklaşım.

Kullanırım:

  • üyeler için m
  • Sabitler / readonly'ler için c
  • işaretçi için p (ve işaretçi-işaretçi için pp)
  • uçucu için v
  • statik için s
  • dizinler ve yineleyiciler için i
  • e olaylar için

Türü açık hale getirmek istediğimde , standart ekler kullanıyorum (örneğin, List, ComboBox, vb.).

Bu, programcı değişkeni her gördüğünde / kullandığında kullanımından haberdar eder. Muhtemelen en önemli durum işaretçi için "p" dir (çünkü kullanım var. 'Dan var->' a değişir ve işaretçiler - NULL, işaretçi aritmetiği vb. İle çok daha dikkatli olmanız gerekir), ancak diğerleri çok kullanışlıdır.

Örneğin, aynı değişken adını tek bir işlevde birden çok şekilde kullanabilirsiniz: (burada bir C ++ örneği, ancak birçok dile eşit olarak uygulanır)

MyClass::MyClass(int numItems)
{
    mNumItems = numItems;
    for (int iItem = 0; iItem < mNumItems; iItem++)
    {
        Item *pItem = new Item();
        itemList[iItem] = pItem;
    }
}

Burada görebilirsiniz:

  • Üye ve parametre arasında karışıklık yok
  • Dizin / yineleyici ve öğeler arasında karışıklık yok
  • "Count", "index" gibi genel (belirsiz) adların birçok tuzağından kaçınan, açıkça ilişkili değişkenlerin (öğe listesi, işaretçi ve dizin) kullanılması.
  • Ön ekler "itemIndex" ve "itemPtr" gibi alternatiflere göre yazmayı azaltır (daha kısa ve otomatik tamamlama ile daha iyi çalışır)

"İName" yineleyiciler başka bir büyük nokta ben asla yanlış dizine sahip bir dizini dizin ve başka bir döngü içinde bir döngü kopyalarsanız döngü dizin değişkenlerinden birini yeniden düzenlemek zorunda değilsiniz.

Bu gerçekçi olmayan basit örneği karşılaştırın:

for (int i = 0; i < 100; i++)
    for (int j = 0; j < 5; j++)
        list[i].score += other[j].score;

(bu okunması zordur ve genellikle "j" nin amaçlandığı yerde "i" nin kullanılmasına yol açar)

ile:

for (int iCompany = 0; iCompany < numCompanies; iCompany++)
    for (int iUser = 0; iUser < numUsers; iUser++)
       companyList[iCompany].score += userList[iUser].score;

(çok daha okunabilir ve indeksleme konusundaki tüm karışıklıkları ortadan kaldırır. Modern IDE'lerde otomatik tamamlama ile bu da hızlı ve kolay bir şekilde yazılır)

Bir sonraki avantaj, kod snippet'lerinin herhangi bir bağlam gerektirmemesidir anlaşılması . Bir e-postaya veya belgeye iki satır kod kopyalayabilirim ve bu parçacığı okuyan herkes tüm üyeler, sabitler, işaretçiler, dizinler vb. Arasındaki farkı söyleyebilir. Eklemek zorunda değilim "oh, ve dikkatli ol çünkü 'data' bir işaretçiye işaretçi "dir, çünkü buna 'ppData' denir.

Aynı nedenden dolayı, anlamak için gözlerimi bir kod satırının dışına taşımak zorunda değilim. 'Veri' yerel, parametre, üye veya sabit olup olmadığını bulmak için kod aramak zorunda değilsiniz. İşaretçiyi 'veri' üzerine getirip sonra bir araç ipucunun (bazen hiçbir zaman görünmez) görünmesini beklemek için elimi fareye taşımak zorunda değilim. Böylece programcılar kodu önemli ölçüde daha hızlı okuyabilir ve anlayabilirler , çünkü yukarı ve aşağı arama ya da beklemek için zaman kaybetmezler.

(İşleri yapmak için yukarı aşağı arama yaptığınızı düşünmüyorsanız, bir yıl önce yazdığınız ve o zamandan beri bakmadığınız bazı kodları bulun. Dosyayı açın ve okumadan yaklaşık yarım adım atlayın. Bir şeyin üye, parametre veya yerel olup olmadığını bilmeden önce bu noktadan okuyabilirsiniz.Şimdi başka bir rastgele yere atlayın ... Bu, başka bir kişinin kodundan tek adım attığımızda gün boyu yaptığımız şeydir. veya işlevlerini nasıl arayacağınızı anlamaya çalışmak)

'M' öneki ayrıca (IMHO) çirkin ve garip "this->" gösterimini ve garanti ettiği tutarsızlığı da önler (dikkatli olsanız bile, genellikle 'this-> data' karışımı ile sonuçlanır ve 'data' aynı sınıfta, çünkü hiçbir şey adın tutarlı bir şekilde yazılmasını zorunlu kılmaz).

'Bu' gösterimin belirsizliği gidermesi amaçlanmıştır - ancak neden birisi kasıtlı olarak belirsiz olabilecek kod yazsın? Belirsizlik olacak er ya da geç bir hata neden olur. Ve bazı dillerde 'bu' statik üyeler için kullanılamaz, bu nedenle kodlama stilinizde 'özel durumlar' tanıtmanız gerekir. Her yerde geçerli olan açık, açık ve tutarlı tek bir basit kodlama kuralına sahip olmayı tercih ederim.

Son büyük fayda Intellisense ve otomatik tamamlama. Bir olay bulmak için Windows Formunda Intellisense'i kullanmayı deneyin - olayları bulmak için asla çağırmanız gerekmeyen yüzlerce gizemli temel sınıf yönteminde gezinmeniz gerekir. Ancak her etkinliğin "e" öneki olsaydı, otomatik olarak "e" altındaki bir grupta listelenirdi. Böylece ön ek, intellisense listesindeki üyeleri, constsları, olayları vb. Gruplamak için çalışır ve böylece istediğiniz adları bulmayı çok daha hızlı ve kolay hale getirir. (Genellikle, bir yöntemin kapsamı içinde erişilebilir olan yaklaşık 20-50 değeri (yerel halk, params, üyeler, consts, olaylar) olabilir. Ama öneki yazdıktan sonra (şimdi bir dizin kullanmak istiyorum, bu yüzden 'i yazıyorum. .. '), yalnızca 2-5 otomatik tamamlama seçeneği sunulur.

Tembel bir programcıyım ve yukarıdaki sözleşme bana çok fazla iş kazandırıyor. Daha hızlı kod yazabilirim ve çok daha az hata yaparım çünkü her değişkenin nasıl kullanılması gerektiğini biliyorum.


Karşı argümanlar

Peki, eksileri nelerdir? Öneklere karşı tipik argümanlar şunlardır:

  • "Önek şemaları kötü / kötü" . Kabul ediyorum "m_lpsz" ve ilk kötü düşünülmüş ve tamamen işe yaramaz. Bu nedenle, bağlamınız için uygun olmayan bir şeyi kopyalamak yerine, gereksinimlerinizi desteklemek için tasarlanmış iyi tasarlanmış bir gösterim kullanmanızı öneririm. (İş için doğru aracı kullanın).

  • "Bir şeyin kullanımını değiştirirsem yeniden adlandırmam gerekir" . Evet, elbette öyle yapıyorsunuz, yeniden düzenleme her şeyle ilgili ve IDE'lerin bu işi hızlı ve acısız bir şekilde yapmak için neden yeniden düzenleme araçlarına sahip oldukları. Ön ekler olmadan bile, bir değişkenin kullanımının değiştirilmesi neredeyse kesinlikle isminin değiştirilmesi gerektiği anlamına gelir .

  • "Önekler beni karıştırıyor" . Nasıl kullanılacağını öğrenene kadar her araçta olduğu gibi. Beyniniz adlandırma modellerine alıştıktan sonra, bilgileri otomatik olarak filtreleyecek ve öneklerin artık orada olduğunu aklınızdan çıkarmayacaksınız. Ama gerçekten "akıcı" hale gelmeden önce bir veya iki hafta boyunca böyle bir şema kullanmalısınız. Ve o zaman birçok insan eski koda bakar ve iyi bir önek şeması olmadan nasıl başardıklarını merak etmeye başlar .

  • "Ben sadece bu şeyleri çözmek için koda bakabilirsiniz" . Evet, ancak kodun başka bir yerine bakarken ya da cevabın gözünüze odaklandığı noktada doğru olduğunda her küçük detayını hatırlayarak zaman kaybetmenize gerek yoktur.

  • Bu bilgilerin bir kısmı değişkenime bir araç ipucu gelmesini bekleyerek bulunabilir . Evet. Desteklendiğinde, bazı önek türleri için, kodunuz temiz bir şekilde derlendiğinde, bir beklemeden sonra, bir açıklamayı okuyabilir ve önekin anında ileteceği bilgileri bulabilirsiniz. Ön ekin daha basit, daha güvenilir ve daha verimli bir yaklaşım olduğunu hissediyorum.

  • "Daha çok yazıyor" . Gerçekten mi? Bir karakter daha mı? Yoksa - IDE otomatik tamamlama araçlarıyla, her önek karakteri arama alanını önemli ölçüde daralttığı için genellikle yazmayı azaltır. "E" tuşuna bastığınızda sınıfınızdaki üç olay akıllıca açılır. "C" ye bastığınızda beş sabit listelenir.

  • "Bunun this->yerine kullanabilirim m" . Evet, yapabilirsin. Ama bu sadece daha çirkin ve daha ayrıntılı bir önek! Sadece çok daha büyük bir risk taşır (özellikle ekiplerde) çünkü derleyici için isteğe bağlıdır ve bu nedenle kullanımı genellikle tutarsızdır. mÖte yandan kısa, net, açık ve isteğe bağlı değildir, bu yüzden onu kullanarak hata yapmak çok daha zordur.


6
Hungarien Notasyonu ile ilgili sorunun Simonyi'nin yanlış anlaşılmasından kaynaklandığını okumuştum. Değişmez türün türünü belirtmek için bir önek kullanılmalıdır, burada "tür" demek istediği gibi "tür bir şey" anlamına gelmez. Daha sonra Microsoft'taki platform adamları onu aldı ve lpsz ile geldi ... ve gerisi tarih ...
VoidPointer

19
"s statik içindir" bana oldukça Macarca "kötü" formu gibi geliyor.
jalf

6
@Mehrdad: zBu tür düşük seviyeli uygulama detaylarının bir sınıfta kapsüllenmesi gereken C ++ gibi bir dilde çok yararlı olduğunu düşünmüyorum , ancak C'de (sıfır sonlandırmanın önemli bir ayrım olduğu) size katılıyorum. Kullandığımız herhangi bir şema IMO'nun kendi ihtiyaçlarımıza en uygun şekilde uyarlanması gerekir - Dolayısıyla, sıfır sonlandırma değişkenin kullanımınızı etkiliyorsa, "z" yi yararlı bir önek olarak bildirmek yanlış olmaz.
Jason Williams

14
The most important case is "p" for pointer (because the usage changes from var. to var-> and you have to be much more careful with pointers.Ben yürekten katılmıyorum. Bir işaretçi yanlış kullanırsam, derlemek olmaz ( void*çift ​​işaretçiler için bir istisna olabilir). Ve bütün ->aşkın .bir işaretçi olduğunu söyle yeter. Ayrıca, otomatik tamamlama kullanıyorsanız, düzenleyicinizde muhtemelen değişken bilgi önekleme ihtiyacını ortadan kaldıran bildirim araç ipuçları bulunur. Ne olursa olsun, iyi cevap.
Thomas Eding

5
Açık, kapsamlı ve ilginç açıklamalar için seçildi, ancak burada bunun C ++ YET'de nasıl zaman kazandırdığını gösteren çok az şey var, diğer birçok dilde büyük ölçüde kullanılmıyor.

115

Genelde üye değişkenler için önek kullanmıyorum.

mBirisi "C ++ zaten üye erişimi için standart bir önek var: işaret kadar bir önek kullanırdım this->.

Şimdi kullandığım şey bu. Yani, belirsizlik olduğundathis-> öneki eklerim , ancak genellikle belirsizlik yoktur ve doğrudan değişken adına doğrudan başvurabilirim.

Bana göre, bu her iki dünyanın da en iyisi. İhtiyacım olduğunda kullanabileceğim bir ön ekim var ve mümkün olduğunda dışarıda bırakmakta özgürüm.

Tabii ki, bunun bariz karşıtı "evet, ama sonra bir değişkenin sınıf üyesi olup olmadığını bir bakışta göremezsiniz".

Ben buna "yani ne? Bunu bilmeniz gerekiyorsa, sınıfınızın muhtemelen çok fazla durumu vardır. Veya fonksiyon çok büyük ve karmaşıktır" diyorum.

Uygulamada, bunun son derece iyi çalıştığını gördüm. Ek bir bonus olarak, yerel bir değişkeni yeniden adlandırmak zorunda kalmadan bir sınıf üyesine (veya başka bir şekilde) kolayca tanıtmamı sağlar.

Ve en iyisi, tutarlı! Tutarlılığı korumak için özel bir şey yapmam veya herhangi bir sözleşmeyi hatırlamam gerekmiyor.


Bu arada, olmamalıdır Sınıf üyeleri için alt çizgi lider kullanın. Uygulama tarafından ayrılan isimlere rahatsız edici bir şekilde yaklaşırsınız.

Standart, çift alt çizgi veya alt çizgi ile başlayan tüm adları büyük harfle ayırır. Ayrıca , global ad alanında tek bir alt çizgiyle başlayan tüm adları saklı tutar .

Bu nedenle, önce alt çizgi ve ardından küçük harf içeren bir sınıf üyesi yasaldır, ancak er ya da geç aynı şeyi büyük harfle başlayan bir tanımlayıcıya yapacaksınız ya da yukarıdaki kurallardan birini ihlal edeceksiniz.

Bu nedenle, alt çizgi çizmekten kaçınmak daha kolaydır. Değişken adında kapsamı kodlamak istiyorsanız bir postfix alt çizgisi veya bir m_veya sadece mönek kullanın.


"Bu nedenle, alt çizgi ve ardından küçük harf içeren bir sınıf üyesi yasaldır, ancak er ya da geç, büyük harfle başlayan bir tanımlayıcıyla aynı şeyi yaparsınız ya da yukarıdaki kurallardan birini ihlal edersiniz." - sınıf üyesi değişkenleri genel ad alanında değildir, bu nedenle küçük veya büyük bir harf izlese de önde gelen alt çizgi güvenlidir.
mbarnett

3
@mbarnett: Hayır, alt çizgi ve büyük harf yalnızca genel ad alanında değil , genel olarak ayrılmıştır .
jalf

9
bu cevabın oyunun önekten daha az olmasına şaşırdı.
Marson Mao

Bu yanıta katılıyorum, sadece this->bir üye değişkeni olduğunu belirtmeniz gerekiyorsa kullanın, ya da etmeyin, bu da iyi.
David Morton

Ayrıca, kodunuzu başkalarına vermek için sözleşmenizi belgelemeniz gerekmez. Herkes ne this->anlama geldiğini anlıyor .
Caduchon

34

Postfix alt çizgilerini tercih ederim, şöyle:

class Foo
{
   private:
      int bar_;

   public:
      int bar() { return bar_; }
};

Ben de. Aynı zamanda erişimcilere / mutasyonculara da aynı adı veriyorum.
Rob

4
İlginç. İlk başta biraz çirkin gözüküyor ama nasıl faydalı olabileceğini görebiliyorum.
ya23

6
"MBar" veya "m_bar" dan çok daha az çirkin olduğunu söyleyebilirim.
sydan

6
ama sonra var vector<int> v_;ve yazma v_.push_back(5)da oldukça çirkin
avim

4
Bu Google C ++ stili.
Justme0

20

Son zamanlarda hiç önek yerine m_ önekini tercih etme eğilimindeyim, nedenleri üye değişkenleri işaretlemek için çok önemli değil, ancak belirsizliği önlüyor, şöyle kodunuz var:

void set_foo(int foo) { foo = foo; }

Sebep bu işe yaramıyor, sadece bir tanesine fooizin var. Yani seçenekleriniz:

  • this->foo = foo;

    Bunu sevmiyorum, çünkü parametre gölgelendirmesine neden olduğundan, artık g++ -Wshadowuyarıları kullanamazsınız , o zaman yazmak da daha uzun m_. Ayrıca, a int foo;ve a öğeleriniz olduğunda değişkenler ve işlevler arasında adlandırma çakışmaları yaşarsınız int foo();.

  • foo = foo_; veya foo = arg_foo;

    Bunu bir süredir kullanıyorum, ancak argüman listelerini çirkin kılıyor, belgelerin uygulamada ad belirsizliği ile uğraşmaması gerekiyordu. Değişkenler ve işlevler arasındaki adlandırma çakışmaları da burada mevcuttur.

  • m_foo = foo;

    API Belgeleri temiz kalır, üye işlevleri ve değişkenleri arasında bir belirsizlik olmaz ve yazılması daha kısa olur this->. Tek dezavantajı, POD yapılarını çirkin hale getirmesidir, ancak POD yapıları ilk etapta isim belirsizliğinden muzdarip olmadığından, onlarla birlikte kullanılması gerekmez. Benzersiz bir ön eke sahip olmak, birkaç arama ve değiştirme işlemini de kolaylaştırır.

  • foo_ = foo;

    Uygulamanın avantajlarının çoğu m_, ancak estetik nedenlerle reddediyorum, izleyen veya önde gelen bir alt çizgi, değişkenin eksik ve dengesiz görünmesini sağlar. m_sadece daha iyi görünüyor. Kullanılması m_kullanabilirsiniz olarak, aynı zamanda daha uzatılabilir olduğu g_globaller için ve s_statik için.

Not: m_Python veya Ruby'de görmemenizin nedeni, her iki dilin kendi önekini uygulaması, Ruby'nin @üye değişkenleri için kullanması ve Python'un gerektirmesidir self..


1
adil olmak gerekirse, en az 2 başka seçeneği kaçırdınız, örneğin (a) fooyalnızca üyeler gibi tam adlar kullanın ve bunun yerine parametreler veya diğer yerel ayarlar / gecikmeler için tek harfli veya kısa adlar kullanın int f; veya (b) parametrelerin veya diğer yerel ayarların önüne bir şey ekleyin. yine de iyi bir nokta m_ve bakla; bağımsız olarak, çoğunlukla bu yönergeleri takip bir tercihe geldi.
underscore_d

12

Bir üye işlevini okurken, değişkenin anlamını anlamak için her değişkenin kimin "sahibi" olduğunu bilmek kesinlikle şarttır. Bunun gibi bir işlevde:

void Foo::bar( int apples )
{
    int bananas = apples + grapes;
    melons = grapes * bananas;
    spuds += melons;
}

... elmaların ve muzların nereden geldiğini görmek yeterince kolay, peki ya üzüm, kavun ve spuds? Global isim alanına bakmalı mıyız? Sınıf bildirisinde? Değişken bu nesnenin bir üyesi mi yoksa bu nesne sınıfının bir üyesi mi? Bu soruların cevabını bilmeden kodu anlayamazsınız. Ve daha uzun bir fonksiyonda, elma ve muz gibi yerel değişkenlerin beyanları bile karışıklıkta kaybolabilir.

Globaller, üye değişkenler ve statik üye değişkenler (belki de sırasıyla g_, m_ ve s_) için tutarlı bir etiket hazırlamak durumu anında netleştirir.

void Foo::bar( int apples )
{
    int bananas = apples + g_grapes;
    m_melons = g_grapes * bananas;
    s_spuds += m_melons;
}

Bunlar ilk başta alışmaya biraz zaman alabilir - ama sonra programlamada ne yapılmaz? {Ve} bile garip göründüğün bir gün vardı. Onlara alıştıktan sonra, kodu çok daha hızlı anlamanıza yardımcı olurlar.

(M_ yerine "this->" kullanmak mantıklıdır, ancak daha uzun soluklu ve görsel olarak yıkıcıdır. Üye değişkenlerin tüm kullanımlarını işaretlemek için iyi bir alternatif olarak görmüyorum.)

Yukarıdaki argümana olası bir itiraz, argümanı türlere genişletmek olacaktır. Bir değişkenin türünü bilmenin "değişkenin anlamını anlamak için kesinlikle gerekli" olduğu da doğru olabilir. Öyleyse, neden her bir değişken adına türünü tanımlayan bir önek eklemiyorsunuz? Bu mantıkla, Macarca gösterimle sonuçlanırsınız. Ancak birçok kişi Macar gösterimini zahmetli, çirkin ve yararsız buluyor.

void Foo::bar( int iApples )
{
    int iBananas = iApples + g_fGrapes;
    m_fMelons = g_fGrapes * iBananas;
    s_dSpuds += m_fMelons;
}

Macarca yaparbize kod hakkında yeni bir şeyler söyleyin. Artık Foo :: bar () işlevinde bazı örtülü dökümler olduğunu anlıyoruz. Şimdi kod ile ilgili sorun Macarca önekleri tarafından eklenen bilgilerin değerinin görsel maliyete göre küçük olmasıdır. C ++ tip sistemi, tiplerin birlikte iyi çalışmasına veya bir derleyici uyarısı veya hatası oluşturmasına yardımcı olan birçok özellik içerir. Derleyici, türlerle başa çıkmamıza yardımcı olur - bunu yapmak için notasyona ihtiyacımız yoktur. Foo :: bar () içindeki değişkenlerin muhtemelen sayısal olacağı kadar kolayca çıkarabiliriz ve bildiğimiz her şey buysa, bu fonksiyonun genel olarak anlaşılmasını sağlayacak kadar iyidir. Bu nedenle, her değişkenin kesin tipini bilmenin değeri nispeten düşüktür. Yine de "s_dSpuds" (hatta sadece "dSpuds") gibi bir değişkenin çirkinliği mükemmeldir. Yani,


S_ fikri için teşekkürler. Çok faydalı görünüyor ve bir şekilde bana hiç gelmemişti.
Chris Olsen

10

Ne kadar yaygın olduğunu söyleyemem, ama kişisel olarak, üye değişkenlerime daima 'm' öneki ekledim. Örneğin:

class Person {
   .... 
   private:
       std::string mName;
};

Kullandığım tek önek biçimidir (ben çok Macarca gösterimlerim) ama yıllar içinde beni iyi bir şekilde durdu. Bir yana, genellikle adlarda alt çizgi kullanımını (veya bu konuda başka bir yerde) mahrum bırakıyorum, ancak genellikle hepsi büyük harf olduğu için önişlemci makro adları için bir istisna yapıyorum.


5
M_ (veya _) yerine m kullanmayla ilgili problem, deve davası için mevcut modada bazı değişken adlarının okunmasını zorlaştırıyor.
Martin Beckett

1
@Neil ben seninleyim. @mgb: '_' ile başlayan isimlerden nefret ediyorum. Bu sadece gelecekte işler ters gidebilir.
Martin York

1
@Neil: Alt çizgi kullanmıyorsanız ve deve kullanmıyorsanız hangi kuralı kullanıyorsunuz?
jalf

2
Benim anlayış camelCase 'apData' kafa karıştırıcı gibi değişkenler için sadece m kullanarak yapar - 'm_apData' yerine 'mapData' olur. Korumalı / özel üye değişkenler için _camelCase kullanıyorum çünkü öne çıkıyor
Martin Beckett

10
@MartinBeckett: Bu asenaryoda büyük harf kullanmalısınız - aksi takdirde doğru şekilde yapmıyorsunuz. mApData( mönek, değişken adı apData).
Platinum Azure

8

Bir üye önekinin ana nedeni, yerel bir üye işlevi ile aynı ada sahip bir üye değişkeni ayırt etmektir. Nesnenin adıyla getters kullanıyorsanız bu yararlıdır.

Düşünmek:

class person
{
public:
    person(const std::string& full_name)
        : full_name_(full_name)
    {}

    const std::string& full_name() const { return full_name_; }
private:
    std::string full_name_;
};

Bu durumda üye değişkeni full_name olarak adlandırılamaz. Get_full_name () için üye işlevini yeniden adlandırmanız veya üye değişkenini bir şekilde dekore etmeniz gerekir.


1
Önek önemin nedeni bu. Bence bence foo.name()çok daha okunaklı foo.get_name().
Terrabits

6

Bir sözdiziminin diğerine göre gerçek değeri olduğunu düşünmüyorum. Tüm bunlar, sizin de bahsettiğiniz gibi, kaynak dosyalardaki tekdüzeliğe kaynar.

Bu tür kuralları ilginç bulduğum tek nokta, aynı adlı 2 şeye ihtiyacım olduğunda, örneğin:

void myFunc(int index){
  this->index = index;
}

void myFunc(int index){
  m_index = index;
}

Ben ikisini farklılaştırmak için kullanıyorum. Ayrıca ben Dll, pencerelerden gibi, aramaları sarın zaman RecvPacket (...) Dll dan sarılmış olabilir RecvPacket (...) benim kod. Bu belirli durumlarda "_" gibi bir önek kullanmak, ikisinin birbirine benzemesini sağlayabilir, hangisinin hangisi olduğunu, ancak derleyici için farklı olduğunu belirleyebilir


6

Bazı yanıtlar, okunabilirliği artırmanın bir yolu olarak, kuralları adlandırmak yerine yeniden düzenlemeye odaklanır. Birinin diğerinin yerini alabileceğini düşünmüyorum.

Yerel bildirimleri kullanmaktan rahatsız olan programcıları tanıyorum; tüm bildirimleri bir bloğun üstüne (C'deki gibi) yerleştirmeyi tercih ederler, böylece onları nerede bulacaklarını bilirler. Kapsam belirlemeye izin veren yerlerde, değişkenlerin ilk kullanıldıkları yerlerde bildirilmesinin, bildirimleri bulmak için geriye doğru baktığım zamanı azalttığını buldum. (Bu benim için küçük fonksiyonlar için bile geçerlidir.) Bu, baktığım kodu anlamamı kolaylaştırıyor.

Umarım bunun üye adlandırma kurallarıyla ne kadar alakalı olduğu açıktır: Üyelerin tek biçimli önekleri olduğunda, asla geriye bakmak zorunda kalmam; Beyannamenin kaynak dosyada bile bulunmayacağını biliyorum.

Bu stilleri tercih etmeye başlamadığımdan eminim. Ancak zamanla, sürekli kullanıldıkları ortamlarda çalışarak, onlardan yararlanmak için düşüncemi optimize ettim. Şu anda onlardan rahatsızlık duyan birçok insanın tutarlı bir kullanım göz önüne alındığında onları tercih etmeye gelebileceğini düşünüyorum.


5

Bu sözleşmeler sadece bu. Çoğu mağaza, kod okunabilirliğini kolaylaştırmak için kod kurallarını kullanır, böylece herkes bir koda kolayca bakabilir ve genel ve özel üyeler gibi şeyler arasında hızlı bir şekilde deşifre edebilir.


"kamu ve özel üyeler arasında" - bu gerçekten ne kadar yaygın? onu hatırlamak hatırlamıyorum, ama sonra tekrar, kod tabanlarını ya da bir şey gözden geçirme dolaşmayın.
underscore_d

Kendi kodlamamda yapmıyorum, ancak kod kongre kılavuzlarına dayanarak yapmak zorunda olduğumuz yerlerde çalıştım. Neredeyse tüm IDE'ler özel değişkenlere farklı bir renk göstereceğinden bunu yapmamayı tercih ediyorum.
Bay Will

Hmm, sanırım sadece benimkinden farklı durumlarda oluyor. Normalde classüyeleri private/ olan tüm es protected, veya structdeğişkenleri public(ve genellikle de const) POD s kullanın . Bu yüzden, herhangi bir üyenin erişim düzeyini asla merak etmem gerekmiyor.
underscore_d

5

Diğerleri, bir üye değişkeni kullanıldığında bu üyeyi kullanarak zorlamaya çalışır.

Bunun nedeni genellikle önek olmamasıdır . Derleyici, önek nedeniyle benzersiz bir ad olsun veya söz konusu değişkeni çözmek için yeterli bilgiye ihtiyaç duyarthis anahtar kelime .

Yani, evet, bence önekler hala yararlı. Birincisi, 'this->' yerine bir üyeye erişmek için '_' yazmayı tercih ederim.


3
derleyici yine de çözebilir ... yerel değişkenler çoğu dilde daha yüksek kapsamda gizleyecektir. Bu, kodu okuyan insanların (şüpheli) yararı içindir. İyi bir IDE, yerlileri / üyeleri / küreselleri farklı şekillerde vurgulayacaktır, bu nedenle bu tür şeylere gerek yoktur
rmeador

1
Kesinlikle. Yerel halk sınıf üyelerini gizleyecek. Bu üyeleri ayarlayan bir kurucu düşünün. Genellikle parametreleri üyelerle aynı şekilde adlandırmak mantıklıdır.
Kent Boogaart

6
Neden bir kod kokusu? Özellikle inşaatçılar söz konusu olduğunda, oldukça yaygın ve makul olduğunu söyleyebilirim.
Kent Boogaart

3
Bir kurucu (genellikle) yerelleştirme listesini başlatma listesinde ayarlamalıdır. Ve orada, parametreler alan adlarını gölgelemez, ancak her ikisine de erişilebilir - böylece yazabilirsinizstruct Foo { int x; Foo(int x) : x(x) { ... } };
Pavel Minaev

2
Foo(int x, bool blee) : x(x) { if (blee) x += bleecount; } // oops, forgot this->Üye değişkenlerime yararlı bir şey çağırmayı tercih edip sonra kısaltılmış isimlerle eşleşen yapıcı parametrelerini vermeyi tercih ettiğimde problem olduğunu varsayıyorum :Foo(int f) : foo(f) {...}
Steve Jessop

4

Diğer diller kodlama kurallarını kullanacak, sadece farklı olma eğilimindedirler. Örneğin, C #, muhtemelen C ++ yöntemlerinden biri (_variable, mVariable veya Macarca gösterim gibi başka bir önek) veya StyleCop yöntemi olarak adlandırdığım iki farklı stile sahiptir.

private int privateMember;
public int PublicMember;

public int Function(int parameter)
{
  // StyleCop enforces using this. for class members.
  this.privateMember = parameter;
}

Sonunda, insanların bildikleri ve en iyi görünenleri olur. Şahsen kodun Macar notasyonu olmadan daha okunabilir olduğunu düşünüyorum, ancak örneğin Macar notasyonu eklenmişse akıllı bir değişken bulmak daha kolay olabilir.

Yukarıdaki örneğimde, kullanım değişkenlerinize önek eklediğinden, üye değişkenler için m önekine ihtiyacınız yoktur. derleyici tarafından uygulanan bir yöntemde aynı şeyi belirtir.

Bu mutlaka diğer yöntemlerin kötü olduğu anlamına gelmez, insanlar işe yarayan şeylere bağlı kalırlar.


3

Büyük bir yöntem veya kod bloğunuz olduğunda, yerel bir değişken veya üye kullanıp kullanmadığınızı hemen bilmek uygun olur. hataları önlemek ve daha iyi netlik için!


3
Büyük bir yönteminiz varsa, daha iyi netlik için onu parçalayın.
sbi

4
Bazı büyük yöntemleri yıkmamak için birçok neden var. Örneğin, yönteminizin çok fazla yerel durumu tutması gerekiyorsa, alt yöntemlerinize çok sayıda parametre iletmeniz, yalnızca bu yöntemler arasında veri iletmek veya durum verilerini şu şekilde bildirmek amacıyla var olan yeni sınıflar oluşturmanız gerekir. üst sınıfın üye verileri. Bunların hepsinde, tek bir uzun-ish yöntemine (özellikle mantığı basit olan) kıyasla yöntemin netliğini veya sürdürülebilirliğini etkileyecek problemler vardır.
Steve Broberg

3
@sbi: Kılavuz ilkeler sadece; kurallar değil, kurallar. Bazen mantıklı bir şekilde bölünmeye yol açmayan büyük yöntemlere ihtiyacınız olur ve bazen parametre adları üyelerle çakışır.
Ed

Lütfen üye değişkenlerinizi herkese açık yapmayın. Sadece erişimcileri kullanın. Parantezler okuyucuya üye değişken olduğunu söylemelidir.
jkeys

Adların çakışmasını tespit etmek için -Wshadow
gcc'de

3

IMO, bu kişisel. Hiç önek koymuyorum. Her neyse, kodun genel olması gerekiyorsa, daha iyi bazı önekleri olması gerektiğini düşünüyorum, bu yüzden daha okunabilir olabilir.

Genellikle büyük şirketler kendi geliştirici kurallarını kullanırlar.
Btw, gördüğüm en komik ama en akıllı DRY KISS (Dont Repself Yourself. Basit, aptal). :-)


3

Diğerlerinin daha önce söylediği gibi, konuşma dili (adlandırma stillerini ve kurallarını yazdığınız kod tabanına uyarlayın) ve tutarlı olmak önemlidir.

Yıllardır "this->" kuralını kullanan ve bir postfix kullanan büyük bir kod tabanı üzerinde çalıştım üye değişkenleri için alt çizgi notasyonu . Yıllar boyunca, bazılarının üye değişkenlerini adlandırmak için herhangi bir konvansiyonu olmayan, diğerlerinde üye değişkenleri adlandırmak için farklı kuralları olan daha küçük projeler üzerinde çalıştım. Bu küçük projeler arasında, herhangi bir konvansiyona sahip olmayanları, hızlı bir şekilde atlamak ve anlamak en zor olanı buldum.

Adlandırma konusunda çok analistim. Bir sınıfa veya değişkene atfedilecek isme üzüleceğim ki, "iyi" olduğunu düşündüğüm bir şey bulamazsam, saçma sapan bir şey söylemeyi ve gerçekten ne olduğunu açıklayan bir yorum sunmayı seçeceğim. dır-dir. Bu şekilde, en azından isim, tam olarak ne demek istediğimi ifade ediyor - daha fazla ve daha az değil. Ve sık sık, bir süre kullandıktan sonra, adın gerçekten ne olması gerektiğini keşfeder ve geri dönüp uygun şekilde değiştirebilir veya yeniden düzenleyebilir .

İşi yapan bir IDE konusunda son bir nokta - hepsi güzel ve iyi, ancak IDE'ler çoğu zaman en acil işi yaptığım ortamlarda mevcut değil. Bazen bu noktada mevcut olan tek şey 'vi'nun bir kopyasıdır. Ayrıca, IDE kod tamamlama adlarında yanlış yazım gibi aptallık yaydığı birçok durum gördüm. Bu nedenle, bir IDE koltuk değerine güvenmemeyi tercih ediyorum.


3

C ++ üye değişkenlerindeki önekler için orijinal fikir, derleyicinin bilmediği ek tür bilgilerini saklamaktı. Örneğin, sabit bir karakter uzunluğuna sahip bir dize, değişken ve bir '\ 0' ile sonlandırılmış bir dizeniz olabilir. Derleyiciye ikisi de char *, ama birinden diğerine kopyalamaya çalışırsanız büyük bir sorunla karşılaşıyorsunuz. Yani, başımın üstünden,

char *aszFred = "Hi I'm a null-terminated string";
char *arrWilma = {'O', 'o', 'p', 's'};

burada "asz" bu değişkenin "ascii dizesi (sıfır sonlandırılmış) ve" arr "bu değişkenin bir karakter dizisi olduğu anlamına gelir.

Sonra sihir olur. Derleyici bu ifadeden çok memnun olacak:

strcpy(arrWilma, aszFred);

Ama siz, bir insan olarak, ona bakıp "hey, bu değişkenler gerçekten aynı tipte değil, bunu yapamam" diyebilirsiniz.

Ne yazık ki pek çok yer üye değişkenleri için "m_", nasıl kullanılırsa kullanılsın tamsayılar için "i", char işaretçileri için "cp" gibi standartlar kullanır. Başka bir deyişle, derleyicinin bildiklerini çoğaltırlar ve aynı anda kodun okunmasını zorlaştırırlar. Bu zararlı uygulamanın yasal olarak yasaklanması ve sert cezalara tabi olması gerektiğine inanıyorum.

Son olarak bahsetmem gereken iki nokta var:

  • C ++ özelliklerinin mantıklı kullanımı, derleyicinin ham C stili değişkenlerde kodlamak zorunda olduğunuz bilgileri bilmesini sağlar. Yalnızca geçerli işlemlere izin verecek sınıflar oluşturabilirsiniz. Bu pratik olduğu kadar yapılmalıdır.
  • Kod blokları çok uzun unutmak ise kullanmadan önce ne değişkeni yazın olduklarını olduğu yolu çok uzun. Adları kullanmayın, yeniden düzenleyin.

Değişken türünü veya türünü gösteren önekler de tartışmaya değer bir şeydir, ancak temelde bir şeyin (özel) üye / alan olup olmadığını gösteren öneklerden bahsediyordum. Bahsettiğiniz ters Macar notasyonu, akıllıca uygulandığında (örneğin örneğiniz gibi) oldukça kullanışlı olabilir. Anlamlı olduğu en sevdiğim örnek göreceli ve mutlak koordinatlardır. absX = relX gördüğünüzde bir şeyin yanlış olabileceğini açıkça görebilirsiniz. işlevleri buna göre de adlandırabilirsiniz: absX = absFromRel (relX, offset);
VoidPointer

Not: aszFred'in başlatılması sorgulanabilir (değişmez bir dizeye sabit olmayan erişim sunar) ve arrWilma'nın başlatılması bile derlenmez. (Muhtemelen arrWilma'yı bir işaretçi yerine bir dizi olarak ilan etmeyi amaçlamıştınız!) Sorun değil, ancak kafanızın üstünden çıktığını yazdığınızda ... :-)
Niels Dekker

Hata! Kesinlikle haklısın. Çocuklar, bunu evde denemeyin. Bunu yapın: 'const char * aszFred = "Merhaba ben null sonlu bir dizeyim"; char arrWilma [] = {'O', 'o', 'p', 's'}; '
AL Flanagan

3

Projemiz her zaman üye verileri için bir önek olarak "onun", yerel parametreler için bir önek olmadan parametreler için bir önek olarak kullanmıştır. Biraz şirin, ama sistemimizin ilk geliştiricileri tarafından benimsendi, çünkü o sırada kullandığımız bazı ticari kaynak kütüphanelerinin bir sözleşmesi olarak kullanıldığını gördüler (XVT veya RogueWave - belki ikisi de). Böylece şöyle bir şey elde edersiniz:

void
MyClass::SetName(const RWCString &theName)
{
   itsName = theName;
}

Ön ekleri (ve başkaları yok - Macar gösteriminden nefret ediyorum) görmenin en büyük nedeni, bir değişkene atıfta bulunduğunuzu düşündüğünüz kod yazarak belaya girmenizi engellemesidir, ancak gerçekten başka bir değişkene atıfta bulunuyorsunuz aynı kapsamda yerel kapsamda tanımlanır. Aynı kavramı temsil etmek için değişken isimler bulma problemini de önler, ancak yukarıdaki örnek gibi farklı kapsamlarla. Bu durumda, yine de "theName" parametresi için bazı önek veya farklı bir ad bulmanız gerekir - neden her yerde geçerli tutarlı bir kural oluşturmuyorsunuz?

Sadece bunu kullanmak yeterince iyi değil - kodlama hatalarını azalttığımız için belirsizliği azaltmakla ilgilenmiyoruz ve yerel olarak tanımlanmış tanımlayıcılarla isimleri maskelemek bir acı olabilir. Bazı derleyiciler, adı daha geniş bir kapsamda maskelediğiniz durumlar için uyarı yükseltme seçeneğine sahip olabilir, ancak seçtiği çok sayıda üçüncü taraf kitaplığıyla çalışıyorsanız bu uyarılar rahatsız edici olabilir zaman zaman kendinizle çarpışan kullanılmayan değişkenlerin isimleri.

Onun / kendisi gelince - Dürüst olmak gerekirse alt çizgilerden daha kolay yazmak için bir dokunmatik daktilo olarak, mümkünse alt çizgileri önlemek - ev satırları çok fazla germe) ve gizemli bir alt çizgiden daha okunabilir buluyorum.


Bu şimdiye kadar duyduğum en hızlı öğrenme eğrisine sahip en sezgisel çözüm. Konuşulan dillerin hepsiyle başa çıkmak için daha esnek olmasını diliyorum, böylece koddaki belirsizlikleri çözmek için yeni teknikler bulmayı düşünmek zorunda kalmadık.
Güney Ozsan

2

Bunu kullanıyorum çünkü VC ++ 'ın Intellisense sınıfından erişirken ne zaman özel üyeler göstereceğini söyleyemez. Tek gösterge Intellisense listesindeki alan simgesinde küçük bir "kilit" sembolüdür. Sadece özel üyeleri (alanları) tanımlamayı kolaylaştırır. Ayrıca dürüst olmak gerekirse C # bir alışkanlık.

class Person {
   std::string m_Name;
public:
   std::string Name() { return m_Name; }
   void SetName(std::string name) { m_Name = name; }
};

int main() {
  Person *p = new Person();
  p->Name(); // valid
  p->m_Name; // invalid, compiler throws error. but intellisense doesn't know this..
  return 1;
}

2

Sınıf üyelerini üye işlev parametreleri ve yerel değişkenlerden ayırmak için öneklere ihtiyacınız varsa, işlev çok büyük veya değişkenler kötü adlandırılmış olduğunu düşünüyorum. Ne olduğunu kolayca görebilmeniz için ekrana sığmıyorsa, refactor.

Sıklıkla kullanıldıkları yerden bildirildikleri göz önüne alındığında, küresel sabitler (ve küresel değişkenler için isimlendirme sözleşmelerinin nadiren her zaman kullanılmasına ihtiyaç duyulmasına rağmen) mantıklı olduğunu düşünüyorum. Ama aksi halde fazla bir ihtiyaç görmüyorum.

Bununla birlikte, tüm özel sınıf üyelerinin sonuna bir alt çizgi koyardım. Tüm verilerim özel olduğundan, üyelerin sonda alt çizgisi olduğu anlamına gelir. Genellikle bunu yeni kod tabanlarında yapmıyorum, ancak, bir programcı olarak, çoğunlukla eski kodla çalıştığınızdan, hala çok şey yapıyorum. Bu alışkanlığa toleransımın bunu her zaman yaptığımdan ve hala düzenli olarak yaptığımdan mı yoksa üye değişkenlerin işaretlemesinden gerçekten daha anlamlı olup olmadığından emin değilim.


2
Bu benim bu konu hakkındaki hislerimi yansıtıyor. Kod, öneklere başvurulmadan okunabilir olmalıdır. Belki de daha modern dillerde çok fazla önek kullanımı görmüyoruz çünkü kullanıcı toplulukları okunabilirliği bazen C ++ 'da gördüğünüzden biraz daha fazla benimsedi. Tabii ki, C ++ okunabilir ve okunabilir olmalıdır. Sadece yıllar boyunca okunamayan birçok C ++ yazılmıştır.
VoidPointer


1

Bellek yönetimi nedeniyle üye değişkenler ile yerel değişkenler arasında ayrım yapmak yararlıdır. Genel olarak, yığın tahsisli üye değişkenler yıkıcıda yok edilirken, yığın tahsisli yerel değişkenler bu kapsamda yok edilmelidir. Üye değişkenlerine bir adlandırma kuralı uygulamak doğru bellek yönetimini kolaylaştırır.


nasıl yani? Yıkıcı, diğer işlevlerde bildirilen yerel değişkenlere erişemez, bu nedenle orada karışıklık için yer yoktur. Ayrıca, öbeğe ayrılan yerel değişkenler olmamalıdır . Öbek olarak ayrılan üye değişkenler yalnızca RAII sınıflarında var olmalıdır.
jalf

"öbek tahsisli yerel değişkenler olmamalı" biraz güçlü. Ancak, bunları kullandığınızda / kullandığınızda, doğru bir şekilde yerleştirildiklerinden emin olmak çok önemlidir, bu nedenle üye ve yerel değişkenler için disiplinli bir adlandırma kuralı, bunu sağlamak için ölçülemez bir şekilde yardımcı olur.
frankster

1

Kod Tamamlandı, üye değişkenler için m_varname önerir.

M_ gösteriminin hiç yararlı olmadığını düşünmeme rağmen, McConnell'in bir standart oluştururken fikir ağırlığını verirdim.


2
Neden alt çizgiyi açıkladığı sürece değil. Burada birçok kez tavsiye ettiğim "Hızlı Gelişim" kitabının büyük bir hayranıyım, ancak "Kod Tamamlandı" nın çok daha azı (ilk çıktığından beri okumadığımı itiraf edeceğim).

1

Değişken isimlerimin önünde neredeyse hiç önek kullanmıyorum. Yeterince iyi bir IDE kullanıyorsanız, referansları kolayca yeniden düzenleyebilmeniz ve bulabilmeniz gerekir. Çok net isimler kullanıyorum ve uzun değişken isimleri kullanmaktan korkmuyorum. Bu felsefe ile de kapsamda hiç sorun yaşamadım.

Bir önek kullandığım tek zaman imza satırında olurdu. Parametreleri _ ile bir yöntemin önüne ekleyeceğim, böylece etraflarında defalarca programlayabiliyorum.


1

Asla böyle bir önek kullanmamalısınız. Böyle bir önek size herhangi bir avantaj sunuyorsa, genel olarak kodlama stilinizin düzeltilmesi gerekir ve kodunuzun net olmasını önleyen önek değildir. Tipik hatalı değişken adları "diğer" veya "2" yi içerir. Daha fazla olmasını gerektirerek bunu düzeltmezsiniz, geliştiricinin bu değişkenin o işlev bağlamında ne yaptığını düşünmesini sağlayarak düzeltirsiniz. Belki de remoteSide ya da newValue ya da secondTestListener ya da bu kapsamdaki bir şey anlamına geliyordu.

Hala çok ileri yayılan etkili bir anakronizm. Değişkenlerinize önek eklemeyi bırakın ve netliklerinin ne kadar süre kullanıldıklarını yansıtan doğru adları verin. 5 satıra kadar karışıklık olmadan "i" diyebilirsiniz; 50 satırın ötesinde oldukça uzun bir isme ihtiyacınız var.


1

Değişken adlarını içerdikleri değerlere sadece bir anlam vermesi ve bunların isminden nasıl bildirildiği / uygulandığını bırakmasını seviyorum. Değerin ne anlama geldiğini bilmek istiyorum, nokta. Belki de ortalama bir yeniden düzenleme miktarından daha fazlasını yaptım, ama bir şeyin isme nasıl uygulandığını gömmenin yeniden düzenlemeyi olması gerekenden daha sıkıcı hale getirdiğini görüyorum. Nesne üyelerinin nerede veya nasıl bildirildiğini gösteren önekler uygulamaya özeldir.

color = Red;

Çoğu zaman, Red'in bir enum, bir yapı veya herhangi bir şey olup olmadığı umurumda değil ve işlev o kadar büyükse, renk yerel olarak bildirildiğini veya üye olup olmadığını hatırlayamıyorum işlevi daha küçük mantıksal birimlere dönüştürür.

Siklomatik karmaşıklığınız o kadar büyükse, şeylerin adlarına gömülü uygulamaya özgü ipuçları olmadan kodda neler olup bittiğini takip edemezsiniz, büyük olasılıkla işlevinizin / yönteminizin karmaşıklığını azaltmanız gerekir.

Çoğunlukla, sadece bu yapıcıları ve başlatıcıları kullanıyorum.


0

Üye değişkenleri için m_'yi Intellisense ve ilgili IDE işlevlerinden yararlanmak için kullanıyorum. Bir sınıfın uygulanmasını kodlarken m_ yazabilir ve tüm m_ üyeleriyle birlikte gruplanmış combobox'ı görebilirim.

Ama elbette m_'siz sorunsuz yaşayabilirdim. Bu sadece benim çalışma tarzım.


Ayrıca yazabilirsinizthis->
Toast

0

ORTAK VURUŞ SAVAŞI HAVA ARAÇ C ++ KODLAMA STANDARTLARI'na göre (Aralık 2005):

AV Kural 67

Herkese açık ve korunan veriler sınıflarda değil yalnızca yapılarda kullanılmalıdır. Gerekçe: Bir sınıf, verilerine erişimi kontrol ederek değişmezliğini koruyabilir. Ancak, eğer bir sınıf özel olmayanlarsa, sınıf üyelerine erişimi denetleyemez. Bu nedenle, bir sınıftaki tüm veriler özel olmalıdır.

Böylece, "m" öneki tüm verilerin özel olması gerektiği için kullanılmaz hale gelir.

Ancak tehlikeli bir değişken olduğu için p önekini işaretçiden önce kullanmak iyi bir alışkanlıktır.


0

Bu sözleşmelerin birçoğu karmaşık editörlerin olmadığı bir dönemdendir. Her çeşit değişkeni renklendirmenizi sağlayan uygun bir IDE kullanmanızı öneririm. Rengi belirlemek, herhangi bir önekten çok daha kolaydır.

Bir değişken hakkında daha fazla ayrıntı almanız gerekiyorsa, herhangi bir modern IDE, işaret veya imleci üzerine getirerek bunu size gösterebilmelidir. Ve bir değişkeni yanlış bir şekilde kullanırsanız (örneğin. İşleciyle bir işaretçi) yine de bir hata alırsınız.

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.