"M_` değişken öneki ne anlama geliyor?


158

Sık sık görüyorum m_Öğreticilerde, örneklerde ve çoğunlukla oyun geliştirmeyle ilgili diğer kodlarda değişkenler için ( m_World,, m_Sprites...) kullanılan ön ekleri .

İnsanlar neden m_değişkenlere önek ekler ?



18
Macar notasyonu ile akılsızca davayı takip etmeden önce, lütfen Macar notasyonunun gerçekte ne olduğu konusunda biraz tarih kontrolü yapın. Çünkü int iCounter'ı adlandırmak anlamsızdır. Ancak bir int xAnnotationPos ve yAnnotationPos'u adlandırmak mantıklıdır. Anlamsal sürümü kullanın.
AkselK

Bazen, içe aktarılan modüller önek işlevleri ve değişkenleri, böylece kendi kodunuzla bunların üzerine yazma olasılığınız azalır. Belirli bir kullanım için isimleri 'rezerve etmenin' bir yoludur.
earthmeLon

3
"Macar" notasyonu çoğu zaman şiddetle alay edilirken, değişken kapsamı ifade eden özel tadı bazı gerçek avantajlara sahiptir. Değişkenin kapsamını tanımlamaya ek olarak, bir yerel, bir parm ve bir üyenin aynı amaca ve dolayısıyla aynı "anlamsal" ada sahip olması gibi ad çakışmalarını önler. Bu, büyük kod tabanlarının bakımını daha basit ve daha az hataya açık hale getirebilir.
Hot Licks

8
Herhangi bir kodlama standardı lehinde ve aleyhinde argümanlar var, ancak soru açıkça neyin işe yaradığını soruyor m_, ancak buradaki yanıtların yarısı neden herkesin şu anki favorilerinin en iyisi olduğunu düşündüğüne dair bir yorum.
cz

Yanıtlar:


110

Bu, üye değişkenler olan değişkenleri tanımlamak için tipik bir programlama uygulamasıdır. Bu yüzden, onları daha sonra kullanırken, kapsamlarını bilmek için nerede tanımlandıklarını görmenize gerek yok. Bu, kapsamı zaten biliyorsanız ve intelliSense gibi bir şey kullanıyorsanız , ile başlayabilirsiniz m_ve tüm üye değişkenlerinizin bir listesi gösterilir. Macar notasyonunun bir kısmı, buradaki örneklerde kapsamla ilgili kısma bakın .


55
Bir adlandırma kuralı için şimdiye kadarki en kötü argüman, intellisense için ctrl + boşluk tuşlarına basmanız yeterlidir.
orlp

12
@nightcracker ön eki beğenmesem de, m_ yazıp ardından "CTRL + SPACE" yazdığınızda (otomatik değilse) sadece üyelerinizi içeren bir liste aldığınızı söylüyor. Tam olarak iyi bir neden değil ama bu bir artı.
Sidar

14
Aynı şeyi yapmanın daha fazla veya daha az standart yolu olduğundan bahsetmeye değer; "m_variable", "m_Variable", "mVariable", "_variable", "_Variable" ... hangisinin 'en iyi' veya 'doğru' olduğu (veya yapılıp yapılmayacağı) 'kadar tartışmalı ve sonuçsuz bir argüman boşluklar ve sekmeler '. :)
Trevor Powell

52
Ben sadece "this->" kullanmayı tercih ederim - bir nevi "m_" yi gereksiz kılar ve derleyici tarafından zorlandığı için daha da iyidir (teoride "m_" yi herhangi bir değişken türü üzerinde açabilirsiniz; bunu "this-> ile yapamazsınız "). Bir parçam, C ++ 'nın "this->" zorunlu hale getirme konusunda standardize olmasını diliyor. Ama bu bir cevap olmaktan çok tartışma dünyasına giriyor.

4
@LaurentCouvidou, geliştiricilerin m_her ikisinin de önekli üye değişkenleri oluşturmasını gerçekten zorlayamazsınız .
SomeWritesReserved

97

In Temiz Kodu: Çevik Yazılım El Sanatları isimli Elkitabı bu önek kullanımı karşı açık bir öneri yoktur:

Ayrıca m_artık üye değişkenlerine önek eklemenize de gerek yok. Sınıflarınız ve işlevleriniz, onlara ihtiyacınız olmayacak kadar küçük olmalıdır.

Bunun bir örneği (C # kodu) da vardır:

Kötü uygulama:

public class Part
{
    private String m_dsc; // The textual description

    void SetName(string name)
    {
        m_dsc = name;
    }
}

İyi pratik:

public class Part
{
    private String description;

    void SetDescription(string description)
    {
        this.description = description;
    }
}

Biz açıkça belirsizlik (durumunda üye değişkenleri başvurmak için dil yapıları ile saymak yani , descriptionüye ve descriptionparametre): this.


6
İfade şu olabilir: "Bu önekin kullanımına KARŞI açık bir öneri var:"
Xofo

Birisinin yazmasına çok sevindim
dmitreyg

Diğer bir neden, java'da getter / setter'ın getName / setName olarak varsayılmasıdır, bu nedenle getM_name kötüdür ve bunları tek tek işlemeniz gerekir.
Leon

Bunu yazdığınız için teşekkürler. Sadece alıntı yaptığınız kitabın Ağustos 2008'den beri yayınlandığını belirtmek istedim - ve bu kötü uygulamayı bugün yeni kodda buluyorum (2019).
alexlomba87

22

C ++ 'da yaygın bir uygulamadır. Bunun nedeni, C ++ 'da üye işlevi ve üye değişkeni için aynı ada sahip olamamanız ve alıcı işlevlerin genellikle "get" öneki olmadan adlandırılmasıdır.

class Person
{
   public:
      std::string name() const;

   private:
      std::string name; // This would lead to a compilation error.
      std::string m_name; // OK.
};

main.cpp:9:19: error: duplicate member 'name'
      std::string name;
                  ^
main.cpp:6:19: note: previous declaration is here
      std::string name() const;
                  ^
1 error generated.

http://coliru.stacked-crooked.com/a/f38e7dbb047687ad

"Üye" için "m_" durumu. "_" Öneki de yaygındır.

Farklı kurallar / dilbilgisi kullanarak bu sorunu çözen programlama dillerinde kullanmamalısınız.


+1, ancak bu genel uygulamanın yalnızca değişken adıyla "olur" olmasının nereden geldiğine dair bir fikriniz var mı?
Paiusco

@Paiusco Sanırım Ockham'ın usturası. Çatışma yoksa, işlevler gibi diğer yapıların önüne geçmeniz gerekmez.
doc

11

m_Önek genellikle üye değişkenler için kullanılır - Ben onun ana avantajı bir kamu mallarının ve özel üye değişkeni destek o arasında kesin bir ayrım oluşturmaya yardımcı olduğunu düşünüyorum:

int m_something

public int Something => this.m_something; 

Yedek değişkenler için tutarlı bir adlandırma kuralına sahip olmaya yardımcı olabilir ve m_önek, bunu yapmanın bir yoludur - büyük / küçük harfe duyarlı olmayan dillerde çalışan bir yöntemdir.

Bunun ne kadar yararlı olduğu, kullandığınız dillere ve araçlara bağlıdır. Güçlü yeniden düzenleme araçlarına ve intellisense'e sahip modern IDE'lerin bunun gibi kurallara daha az ihtiyacı vardır ve kesinlikle bunu yapmanın tek yolu bu değildir, ancak her durumda uygulamanın farkında olmaya değer.


6
this.Kendi dilinizde yazmanız gerekiyorsa, o m_zaman gerçekten işe yaramaz.
Ruslan

@Ruslan the m_, onu desteklediği mülkten ayırmaktır - yani this.Somethingmülk this.m_somethingve destekleyici üye için. Bu, kendimi tercih ettiğim bir kongre değil, ancak çoğunlukla büyük / küçük harfe duyarlı olmayan dillerde (VB gibi) kullanıldığını gördüm.
Keith

2
Neden this.Somethingmülk this.somethingiçin ve destek için olmasın ? Veya this._somethingdestek için? this.m_somethinggereksizdir. Kullandığım _somethingben yazmaya gittiğimde kaza onu yazmayın böylece Somethingmembershipness ile ya da değil yapmak, hiçbir şey
AustinWBryan

@AustinWBryan, büyük / küçük harfe duyarlı olmayan diller hakkındaki önceki yorumuma bakın. Evet, _kendi başına bir önek işi halledebilirdi, ama m_kuraldır. Kişisel olarak kullanacağım bir şey değil, ama kodda görürseniz yazarın amacı buydu.
Keith

7

Diğer cevaplarda da belirtildiği gibi m_önek, bir değişkenin sınıf üyesi olduğunu belirtmek için kullanılır. Bu, Macar gösteriminden farklıdır çünkü değişkenin türünü değil, içeriğini gösterir.

m_C ++ 'da kullanıyorum , ancak' bu 'veya' kendinin 'zorunlu olduğu diğer bazı dillerde kullanmıyorum . Kodu karıştırdığı için 'this->' nin C ++ ile kullanıldığını görmekten hoşlanmıyorum.

Başka bir cevap diyor m_dsc da "kötü uygulama" ve "açıklama" dır; "iyi bir uygulama" ama bu bir kırmızı ringa balığı çünkü sorun kısaltmadır.

Başka bir cevap, yazmanın thisIntelliSense'i açtığını söylüyor, ancak herhangi bir iyi IDE'nin mevcut sınıf üyeleri için IntelliSense'i açmak için bir kısayol tuşu olacak.


"ama bu kırmızı ringa balığı" - İyi nokta. Adil bir karşılaştırma m_descriptionvs olacaktır description.
Savaş

4

Lockheed Martin, özellikle başkalarının kodunu okurken birlikte çalışması harika olan 3 önekli bir adlandırma şeması kullanıyor.

   Scope          Reference Type(*Case-by-Case)   Type

   member   m     pointer p                       integer n
   argument a     reference r                     short   n
   local    l                                     float   f
                                                  double  f
                                                  boolean b

Yani...

int A::methodCall(float af_Argument1, int* apn_Arg2)
{
    lpn_Temp = apn_Arg2;
    mpf_Oops = lpn_Temp;  // Here I can see I made a mistake, I should not assign an int* to a float*
}

Değeri ne olursa olsun al.


Harika. "Örnek" için teşekkürler. Gerçekten kullanışlı olduğu yer, 200.000 satır kodu düzenlediğiniz zamandır.
jiveturkey

1
Savunmaya gerek yok. Cevabınızda bir hata olduğunu size göstererek dürüstçe yardım etmeye çalışıyorum. O halde daha açık konuşayım: 5 veya 200000 satır kodunuz olması önemli değil: Derleyici, uyumsuz işaretçi türleri ile bir atama yapmanıza izin vermez. Yani yorumda belirtilen nokta tartışmalı.
Cássio Renan

Savunma olarak çıkmak istemedim. Afedersiniz.
jiveturkey

Modern dillerde anlam ifade etmeyen Macar notasyonunun bir varyasyonu ...
doc

3

Diğer birçok yanıtta belirtildiği gibi, m_, üye değişkenleri belirten bir önektir. C ++ dünyasında yaygın olarak kullanılır / kullanıldı ve Java dahil diğer dillere de yayıldı.

Modern bir IDE'de, sözdizimi vurgulaması, hangi değişkenlerin yerel ve hangilerinin üye olduğunu açıkça ortaya koyduğundan, tamamen gereksizdir . Bununla birlikte, sözdizimi vurgulaması 90'ların sonlarında ortaya çıktığında, sözleşme uzun yıllardır ortalıktaydı ve sağlam bir şekilde ayarlandı (en azından C ++ dünyasında).

Hangi öğreticilere atıfta bulunduğunuzu bilmiyorum, ancak iki faktörden biri nedeniyle kuralları kullandıklarını tahmin edeceğim:

  • Bunlar, m_ kuralına alışkın kişiler tarafından yazılan C ++ dersleridir ve / veya ...
  • Kodu sözdizimi vurgulamadan düz (tek aralıklı) metin olarak yazarlar, bu nedenle m_ kuralı, örnekleri daha açık hale getirmek için kullanışlıdır.

Bir örnek şu olabilir: wiki.qt.io/How_to_Use_QSettings Qt Creator vurgulamayı kullandığından, ilk tahmin görünebilir. Bir sınıfın özel nesneleri için _object () ve bir işaretçi ise p_variable kullanan başka bir kural biraz farklı olabilir, çünkü her ikisi de bildiğim kadar yüksek değildir ve onu kullanmam için mantıklı görünmektedir.
Ivanovic

2

Mevcut cevapları tamamlamak için ve soru dile özgü olmadığından, bazı C-projeleri m_, bir dosyaya özgü g_genel değişkenleri ve tanımlandıkları dosyadan daha büyük kapsamı olan genel değişkenleri tanımlamak için öneki kullanır .
Bu durumda önek ile tanımlanan global değişkenler m_ olarak tanımlanmalıdır static.

Bkz EDK2 (UEFI Açık Kaynak uygulaması) kodlama kongre bu kuralını kullanarak projenin bir örnek için.


1

Henüz görmediğim bir argüman, 'd makroları m_ile isim çatışmasını önlemek için kullanılabilecek gibi bir önek #define.

Curses / ncurses'dan #define [a-z][A-Za-z0-9_]*[^(]içinde için normal ifade araması /usr/include/term.h.

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.