Apa arti dari awalan variabel `m_`?

155

Saya sering melihat m_awalan yang digunakan untuk variabel ( m_World, m_Sprites, ...) di tutorial, contoh dan kode lain terutama terkait dengan pengembangan game.

Mengapa orang menambahkan awalan m_ke variabel?

kravemir
sumber
18
Sebelum mengikuti dengan hati-hati sesuai dengan notasi hungaria, silakan lakukan pemeriksaan sejarah tentang apa sebenarnya notasi Hungaria. Karena penamaan int iCounter tidak ada gunanya. Tetapi penamaan int xAnnotationPos dan yAnnotationPos masuk akal. Gunakan versi Semantic.
AkselK
Kadang-kadang, modul dan fungsi awalan modul yang diimpor sehingga Anda cenderung menimpa mereka dengan kode Anda sendiri. Ini adalah cara 'pemesanan' nama untuk penggunaan tertentu.
earthmeLon
3
Sementara notasi "Hungaria" sering diejek dengan kejam, aroma tertentu yang menunjukkan ruang lingkup variabel memang memiliki beberapa keunggulan nyata. Selain mengidentifikasi ruang lingkup variabel, itu mencegah tabrakan nama, seperti ketika lokal, parm, dan anggota semua memiliki maksud yang sama, dan karenanya nama "semantik" yang sama. Ini dapat membuat pemeliharaan basis kode besar lebih sederhana dan lebih sedikit rawan kesalahan.
Hot Licks
8
Ada beberapa argumen yang mendukung dan menentang standar pengkodean apa pun, tetapi pertanyaannya dengan jelas menanyakan untuk apa m_, namun separuh tanggapan di sini adalah komentar mengapa semua orang menganggap favorit mereka saat ini adalah yang terbaik.
cz

Jawaban:

108

Ini adalah praktik pemrograman tipikal untuk mendefinisikan variabel yang merupakan variabel anggota. Jadi ketika Anda menggunakannya nanti, Anda tidak perlu melihat di mana mereka ditentukan untuk mengetahui ruang lingkup mereka. Ini juga bagus jika Anda sudah tahu ruang lingkup dan Anda menggunakan sesuatu seperti intelliSense , Anda bisa mulai dengan m_dan daftar semua variabel anggota Anda ditampilkan. Bagian dari notasi Hongaria, lihat bagian tentang cakupan dalam contoh di sini .

MichaelHouse
sumber
51
Argumen terburuk untuk konvensi penamaan yang pernah ada, Anda cukup menekan ctrl + space untuk intellisense.
orlp
11
@nightcracker walaupun saya tidak suka awalan, maksudnya dia mengatakan bahwa ketika anda mengetik m_ dan kemudian "CTRL + SPACE" (kecuali itu otomatis), anda mendapatkan daftar yang hanya berisi anggota anda. Bukan alasan yang tepat tapi itu plus.
Sidar
13
Layak disebutkan bahwa ada banyak cara lain yang kurang lebih standar untuk melakukan hal yang sama; "m_variable", "m_Variable", "mVariable", "_variable", "_Variable" ... jalan mana yang 'terbaik' atau 'benar' (atau apakah akan melakukannya sama sekali) adalah argumen yang kontroversial dan tidak berbuah seperti ' spasi vs tab '. :)
Trevor Powell
49
Saya lebih suka menggunakan "ini->" - agak membuat "m_" berlebihan dan bahkan lebih baik karena diberlakukan oleh kompiler (secara teori Anda dapat memunculkan "m_" pada jenis variabel apa pun; tidak dapat melakukan itu dengan "ini-> "). Sebagian dari saya berharap bahwa C ++ hanya akan standar untuk membuat "ini->" wajib. Tapi itu lebih ke dunia diskusi daripada menjadi jawaban.
3
@LaurentCouvidou, Anda tidak bisa benar-benar menegakkan bahwa devs membuat variabel anggota diawali dengan m_baik.
SomeWritesResterved
94

Dalam Kode Bersih: Buku Panduan Pengerjaan Perangkat Lunak Agile ada rekomendasi eksplisit terhadap penggunaan awalan ini:

Anda juga tidak perlu membuat awalan variabel anggota m_ . Kelas dan fungsi Anda harus cukup kecil sehingga Anda tidak membutuhkannya.

Ada juga contoh (kode C #) ini:

Praktik buruk:

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

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

Praktek yang baik:

public class Part
{
    private String description;

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

Kami menghitung dengan konstruksi bahasa untuk merujuk variabel anggota dalam kasus eksplisit ambiguitas ( yaitu , descriptionanggota dan descriptionparameter): this.

InfZero
sumber
6
Tulisan bisa jadi "ada rekomendasi eksplisit MELAWAN penggunaan awalan ini:"
Xofo
Saya sangat senang seseorang menulisnya
dmitreyg
Alasan lain adalah bahwa dalam java getter / setter diasumsikan getName / setName, jadi getM_name buruk dan Anda perlu menanganinya satu per satu.
Leon
Terima kasih telah menulis ini. Saya hanya ingin menunjukkan bahwa buku yang Anda kutip telah keluar sejak Agustus 2008 - dan saya masih menemukan praktik buruk ini dalam kode baru hari ini (2019).
alexlomba87
20

Ini adalah praktik umum dalam C ++. Ini karena di C ++ Anda tidak dapat memiliki nama yang sama untuk fungsi anggota dan variabel anggota, dan fungsi pengambil sering dinamai tanpa awalan "get".

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

"m_" menyatakan untuk "anggota". Awalan "_" juga umum.

Anda seharusnya tidak menggunakannya dalam bahasa pemrograman yang memecahkan masalah ini dengan menggunakan konvensi / tata bahasa yang berbeda.

dokter
sumber
11

The m_prefix sering digunakan untuk variabel anggota - saya pikir keunggulan utamanya adalah bahwa hal itu membantu menciptakan perbedaan yang jelas antara properti publik dan swasta variabel anggota backing itu:

int m_something

public int Something => this.m_something; 

Ini dapat membantu untuk memiliki konvensi penamaan yang konsisten untuk variabel pendukung, dan m_ awalan adalah salah satu cara untuk melakukan itu - yang berfungsi dalam bahasa yang tidak peka huruf besar-kecil.

Seberapa bermanfaat hal ini tergantung pada bahasa dan alat yang Anda gunakan. IDE modern dengan alat refactor yang kuat dan intellisense memiliki sedikit kebutuhan untuk konvensi seperti ini, dan itu tentu saja bukan satu-satunya cara untuk melakukan ini, tetapi ada baiknya menyadari praktik dalam hal apapun.

Keith
sumber
5
Jika Anda harus menulis this.dalam bahasa Anda, maka m_itu benar-benar tidak berguna.
Ruslan
@Ruslan m_adalah untuk membedakannya dari properti yang didukungnya - jadi this.Somethinguntuk properti vs this.m_somethinguntuk anggota pendukung. Ini bukan konvensi yang saya sukai, tetapi saya sering melihatnya menggunakan bahasa yang tidak sensitif (seperti VB).
Keith
1
Mengapa tidak, this.Somethinguntuk properti dan this.somethingdukungan? Atau this._somethinguntuk dukungannya? this.m_somethingberlebihan. Saya menggunakan _somethingsehingga saya tidak sengaja mengetiknya saat saya mengetik Something, tidak ada hubungannya dengan keanggotaan atau tidak
AustinWBryan
@AustinWBryan melihat komentar saya sebelumnya tentang bahasa yang tidak peka huruf besar-kecil. Ya, _awalan itu sendiri akan melakukan pekerjaan, tetapi m_konvensi. Itu bukan yang saya gunakan secara pribadi, tetapi jika Anda melihatnya dalam kode itu adalah maksud dari penulis.
Keith
7

Seperti yang dinyatakan dalam jawaban lain, m_awalan digunakan untuk menunjukkan bahwa variabel adalah anggota kelas. Ini berbeda dari notasi Hongaria karena tidak menunjukkan jenis variabel tetapi konteksnya.

Saya menggunakan m_dalam C ++ tetapi tidak dalam beberapa bahasa lain di mana 'ini' atau 'diri' adalah wajib. Saya tidak suka melihat 'ini->' digunakan dengan C ++ karena ini mengacaukan kode.

Jawaban lain mengatakan m_dsc"praktik buruk" dan 'deskripsi;' adalah "praktik yang baik" tetapi ini adalah herring merah karena masalahnya ada singkatan.

Jawaban lain mengatakan mengetik thisIntelliSense muncul tetapi setiap IDE yang baik akan memiliki hotkey untuk memunculkan IntelliSense untuk anggota kelas saat ini.

Quentin 2
sumber
"Tapi ini herring merah" - Poin bagus. Sebuah perbandingan yang adil akan m_descriptionvs description.
Pertempuran
3

Seperti yang dinyatakan dalam banyak respons lain, m_ adalah awalan yang menunjukkan variabel anggota. Ini adalah / biasa digunakan di dunia C ++ dan disebarkan ke bahasa lain juga, termasuk Java.

Dalam IDE modern, hal itu sepenuhnya berlebihan karena penyorotan sintaksis membuatnya menjadi bukti variabel mana yang lokal dan mana yang anggota . Namun, pada saat penyorotan sintaksis muncul di akhir 90-an, konvensi telah ada selama bertahun-tahun dan telah ditetapkan dengan kuat (setidaknya di dunia C ++).

Saya tidak tahu tutorial mana yang Anda maksud, tapi saya kira mereka menggunakan konvensi karena salah satu dari dua faktor:

  • Itu adalah tutorial C ++, ditulis oleh orang-orang yang terbiasa dengan konvensi m_, dan / atau ...
  • Mereka menulis kode dalam teks biasa (tanpa spasi), tanpa penyorotan sintaks, sehingga konvensi m_ berguna untuk membuat contoh lebih jelas.
sergut
sumber
Salah satu contohnya adalah ini: wiki.qt.io/How_to_Use_QSettings Karena Qt Creator IS menggunakan highlighting, tebakan pertama mungkin muncul. Agak berbeda mungkin konvensi lain menggunakan _object () untuk objek pribadi kelas dan p_variable jika itu adalah pointer karena keduanya tidak terlalu tinggi seperti yang saya tahu dan tampaknya masuk akal bagi saya untuk menggunakannya.
Ivanovic
3

Lockheed Martin menggunakan skema penamaan 3-awalan yang bagus untuk dikerjakan, terutama ketika membaca kode orang lain.

   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

Begitu...

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*
}

Ambillah untuk apa nilainya.

jiveturkey
sumber
Luar biasa. Terima kasih untuk "contoh". Hal yang sangat berguna adalah ketika Anda mengedit 200.000 baris kode.
jiveturkey
1
Tidak perlu bersikap defensif. Sejujurnya saya mencoba membantu Anda dengan menunjukkan bahwa ada kesalahan dalam jawaban Anda. Biarkan saya menjadi lebih jelas, maka: Tidak masalah jika Anda memiliki 5, atau 200000 baris kode: Compiler tidak akan membiarkan Anda melakukan tugas dengan tipe pointer yang tidak kompatibel. Jadi poin yang dibuat dalam komentar adalah moot.
Cássio Renan
Bukan berarti bersikap defensif. Maaf.
jiveturkey
Ini adalah variasi notasi Hongaria, yang tidak masuk akal dalam bahasa modern ...
doc
2

Untuk menyelesaikan jawaban saat ini dan karena pertanyaannya tidak spesifik bahasa, beberapa proyek-C menggunakan awalan m_untuk mendefinisikan variabel global yang spesifik untuk file - dan g_untuk variabel global yang memiliki cakupan lebih besar dari file yang mereka tetapkan.
Dalam hal ini variabel global yang didefinisikan dengan awalan m_ harus didefinisikan sebagai static.

Lihat konvensi pengkodean EDK2 (implementasi Open-Source UEFI) untuk contoh proyek yang menggunakan konvensi ini.

OlivierM
sumber
1

Satu argumen yang belum saya lihat adalah bahwa awalan seperti itu m_dapat digunakan untuk mencegah perselisihan nama dengan #define'd macro's.

Regex mencari #define [a-z][A-Za-z0-9_]*[^(]masuk /usr/include/term.hdari kutukan / ncurses.

yyny
sumber