Mengapa menggunakan awalan pada variabel anggota di kelas C ++

150

Banyak kode C ++ menggunakan konvensi sintaksis untuk menandai variabel anggota. Contoh umum termasuk

  • m_ memberName untuk anggota publik (di mana anggota publik digunakan sama sekali)
  • _ memberName untuk anggota pribadi atau semua anggota

Yang lain mencoba memberlakukan menggunakan-> anggota ini setiap kali variabel anggota digunakan.

Dalam pengalaman saya, kebanyakan basis kode yang lebih besar gagal menerapkan aturan seperti itu secara konsisten.

Dalam bahasa lain, konvensi ini jauh lebih luas. Saya melihatnya hanya sesekali dalam kode Java atau C #. Saya pikir saya belum pernah melihatnya dalam Ruby atau kode Python. Dengan demikian, tampaknya ada kecenderungan dengan bahasa yang lebih modern untuk tidak menggunakan markup khusus untuk variabel anggota.

Apakah konvensi ini masih berguna hari ini di C ++ atau itu hanya sebuah anakronisme. Terutama karena digunakan begitu tidak konsisten di perpustakaan. Bukankah bahasa lain menunjukkan bahwa seseorang dapat melakukannya tanpa awalan anggota?

VoidPointer
sumber
15
Saya lebih suka itu; dalam basis kode yang kompleks, penting untuk mengetahui vars mana yang lokal dan mana yang tidak. Saya biasanya menggunakan awalan untuk memaksakan ini-> yang saya temukan banyak mengetik dan opsional tambahan (sedangkan penamaan akan memaksa Anda untuk melakukannya)
Joe
5
Anda belum pernah melihatnya di Ruby karena atribut @ for, dan ungkapan membuat pengakses lebih suka menggunakan atribut secara langsung.
Steve Jessop
6
Menurut PEP 8 variabel anggota non-publik harus diawali dengan garis bawah dalam Python (contoh:) self._something = 1.
Nathan Osman
2
Tidakkah penyorotan editor seharusnya digunakan untuk mengidentifikasi ini?
juga
2
Anda telah melihat padanan this->memberdalam kode Python. Dalam Python biasanya self.memberdan tidak hanya konvensi, itu diperlukan oleh bahasa.
matec

Jawaban:

48

Anda harus berhati-hati dengan menggunakan garis bawah utama. Sebuah garis bawah utama sebelum huruf kapital dalam sebuah kata dicadangkan. Sebagai contoh:

_Foo

_L

semuanya adalah kata yang dilindungi undang-undang

_foo

_l

tidak. Ada situasi lain di mana menggarisbawahi menggarisbawahi sebelum huruf kecil tidak diperbolehkan. Dalam kasus khusus saya, saya menemukan _L kebetulan dicadangkan oleh Visual C ++ 2005 dan bentrokan tersebut menciptakan beberapa hasil yang tidak terduga.

Saya berada di pagar tentang betapa berguna untuk menandai variabel lokal.

Berikut ini tautan tentang pengidentifikasi mana yang dicadangkan: Apa aturan tentang menggunakan garis bawah pada pengidentifikasi C ++?

Juan
sumber
4
Sebenarnya, baik _foo dan _l dicadangkan di lingkup namespace.
13
Tetapi mereka ok sebagai nama variabel anggota. Saya tidak awali garis bawah, karena aturannya terlalu membingungkan, dan saya pernah terbakar di masa lalu.
Juan
11
Ini bukan kata-kata yang dicadangkan. Mereka adalah nama yang dipesan. Jika kata-kata itu dilindungi undang-undang, Anda tidak bisa menggunakannya sama sekali. Karena mereka adalah nama yang dicadangkan, Anda dapat menggunakannya, tetapi dengan risiko Anda sendiri.
TonyK
235

Saya mendukung awalan yang dilakukan dengan baik .

Saya pikir (Sistem) Notasi Hungaria bertanggung jawab atas sebagian besar "rap buruk" yang didapatkan oleh awalan.

Notasi ini sebagian besar tidak ada gunanya dalam bahasa yang sangat diketik misalnya dalam C ++ "lpsz" untuk memberi tahu Anda bahwa string Anda adalah pointer panjang ke string nul terminated, ketika: arsitektur tersegmentasi adalah sejarah kuno, string C ++ oleh pointer konvensi umum ke nul-terminated array ar, dan itu tidak terlalu sulit untuk mengetahui bahwa "customerName" adalah string!

Namun, saya menggunakan awalan untuk menentukan penggunaan variabel (pada dasarnya "Apps Hungarian", meskipun saya lebih suka menghindari istilah Hungaria karena memiliki hubungan yang buruk dan tidak adil dengan System Hungarian), dan ini adalah penghemat waktu yang sangat berguna dan pendekatan pengurangan bug .

Saya menggunakan:

  • m untuk anggota
  • c untuk konstanta / readonlys
  • p untuk pointer (dan pp untuk pointer ke pointer)
  • v untuk volatile
  • s untuk statis
  • i untuk indeks dan iterator
  • e untuk acara

Di mana saya ingin memperjelas jenisnya , saya menggunakan sufiks standar (mis. Daftar, ComboBox, dll).

Ini membuat programmer sadar akan penggunaan variabel setiap kali mereka melihat / menggunakannya. Arguably case yang paling penting adalah "p" untuk pointer (karena perubahan penggunaan dari var. Ke var-> dan Anda harus lebih berhati-hati dengan pointer - NULLs, pointer aritmatika, dll), tetapi yang lainnya sangat berguna.

Misalnya, Anda dapat menggunakan nama variabel yang sama dalam berbagai cara dalam satu fungsi: (di sini contoh C ++, tetapi berlaku sama untuk banyak bahasa)

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

Anda bisa lihat di sini:

  • Tidak ada kebingungan antara anggota dan parameter
  • Tidak ada kebingungan antara indeks / iterator dan item
  • Penggunaan satu set variabel yang terkait jelas (daftar item, pointer, dan indeks) yang menghindari banyak jebakan nama generik (samar) seperti "menghitung", "indeks".
  • Awalan mengurangi pengetikan (lebih pendek, dan bekerja lebih baik dengan pelengkapan otomatis) daripada alternatif seperti "itemIndex" dan "itemPtr"

Poin bagus lain dari iterators "iName" adalah bahwa saya tidak pernah mengindeks array dengan indeks yang salah, dan jika saya menyalin sebuah loop di dalam loop lain, saya tidak perlu refactor salah satu variabel indeks loop.

Bandingkan contoh sederhana yang tidak realistis ini:

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

(yang sulit dibaca dan sering mengarah ke penggunaan "i" di mana "j" dimaksudkan)

dengan:

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

(yang jauh lebih mudah dibaca, dan menghilangkan semua kebingungan tentang pengindeksan. Dengan lengkapi-otomatis dalam IDE modern, ini juga cepat dan mudah untuk diketik)

Manfaat berikutnya adalah cuplikan kode tidak memerlukan konteks apa pun untuk dipahami. Saya dapat menyalin dua baris kode ke email atau dokumen, dan siapa pun yang membaca cuplikan itu dapat membedakan antara semua anggota, konstanta, pointer, indeks, dll. Saya tidak perlu menambahkan "oh, dan berhati-hatilah karena 'data' adalah sebuah pointer ke sebuah pointer ", karena itu disebut 'ppData'.

Dan untuk alasan yang sama, saya tidak perlu mengalihkan pandangan dari satu baris kode untuk memahaminya. Saya tidak perlu mencari melalui kode untuk menemukan apakah 'data' adalah lokal, parameter, anggota, atau konstan. Saya tidak perlu memindahkan tangan saya ke mouse sehingga saya bisa mengarahkan kursor ke 'data' dan kemudian menunggu tooltip (yang kadang-kadang tidak pernah muncul) muncul. Jadi programmer dapat membaca dan memahami kode secara signifikan lebih cepat, karena mereka tidak membuang waktu mencari naik dan turun atau menunggu.

(Jika Anda tidak berpikir Anda membuang waktu untuk mencari-cari pekerjaan, temukan beberapa kode yang Anda tulis setahun yang lalu dan belum melihatnya. Buka file dan lompat setengah jalan tanpa membacanya. Lihat caranya jauh Anda dapat membaca dari titik ini sebelum Anda tidak tahu apakah ada anggota, parameter atau lokal. Sekarang lompat ke lokasi acak lain ... Ini adalah apa yang kita semua lakukan sepanjang hari ketika kita tunggal melangkah melalui kode orang lain atau mencoba memahami cara memanggil fungsi mereka)

Awalan 'm' juga menghindari notasi "IMHO-" yang jelek dan bertele-tele, dan ketidakkonsistenan yang dijaminnya (bahkan jika Anda berhati-hati biasanya akan berakhir dengan campuran 'data->' ini dan 'data' di kelas yang sama, karena tidak ada yang mengeja ejaan nama yang konsisten).

Notasi 'ini' dimaksudkan untuk menyelesaikan ambiguitas - tetapi mengapa ada orang yang dengan sengaja menulis kode yang bisa ambigu? Ambiguitas akan menyebabkan bug cepat atau lambat. Dan dalam beberapa bahasa 'ini' tidak dapat digunakan untuk anggota statis, jadi Anda harus memperkenalkan 'kasus khusus' dalam gaya pengkodean Anda. Saya lebih suka memiliki aturan pengkodean tunggal yang berlaku di mana-mana - eksplisit, tidak ambigu dan konsisten.

Manfaat utama terakhir adalah dengan Intellisense dan pelengkapan otomatis. Coba gunakan Intellisense pada Formulir Windows untuk menemukan acara - Anda harus menggulir melalui ratusan metode kelas dasar misterius yang tidak perlu Anda panggil untuk menemukan acara tersebut. Tetapi jika setiap acara memiliki awalan "e", mereka secara otomatis akan terdaftar dalam grup di bawah "e". Dengan demikian, awalan berfungsi untuk mengelompokkan anggota, const, peristiwa, dll dalam daftar intellisense, menjadikannya lebih cepat dan mudah untuk menemukan nama yang Anda inginkan. (Biasanya, suatu metode mungkin memiliki sekitar 20-50 nilai (lokal, params, anggota, consts, peristiwa) yang dapat diakses dalam cakupannya. Tetapi setelah mengetikkan awalan (saya ingin menggunakan indeks sekarang, jadi saya ketik 'i. .. '), saya hanya diberi 2-5 opsi pelengkapan otomatis.' Pengetikan ekstra '

Saya seorang programmer yang malas, dan konvensi di atas menghemat banyak pekerjaan. Saya dapat kode lebih cepat dan saya membuat kesalahan jauh lebih sedikit karena saya tahu bagaimana setiap variabel harus digunakan.


Argumen menentang

Jadi, apa yang kontra? Argumen umum terhadap awalan adalah:

  • "Skema awalan buruk / jahat" . Saya setuju bahwa "m_lpsz" dan sejenisnya dipikirkan dengan buruk dan sepenuhnya tidak berguna. Itu sebabnya saya menyarankan menggunakan notasi yang dirancang dengan baik yang dirancang untuk mendukung kebutuhan Anda, daripada menyalin sesuatu yang tidak pantas untuk konteks Anda. (Gunakan alat yang tepat untuk pekerjaan itu).

  • "Jika saya mengubah penggunaan sesuatu, saya harus mengganti namanya" . Ya, tentu saja, itulah yang dimaksud dengan refactoring, dan mengapa IDE memiliki alat refactoring untuk melakukan pekerjaan ini dengan cepat dan tanpa rasa sakit. Bahkan tanpa awalan, mengubah penggunaan variabel hampir pasti berarti namanya harus diubah.

  • "Awalan hanya membingungkan saya" . Seperti halnya setiap alat sampai Anda belajar bagaimana menggunakannya. Setelah otak Anda terbiasa dengan pola penamaan, itu akan menyaring informasi secara otomatis dan Anda tidak akan keberatan jika awalannya ada lagi. Tetapi Anda harus menggunakan skema seperti ini selama satu atau dua minggu sebelum Anda benar-benar menjadi "fasih". Dan saat itulah banyak orang melihat kode lama dan mulai bertanya-tanya bagaimana mereka berhasil tanpa skema awalan yang baik.

  • "Saya hanya bisa melihat kode untuk menyelesaikan masalah ini" . Ya, tetapi Anda tidak perlu membuang waktu mencari di tempat lain dalam kode atau mengingat setiap detail kecil ketika jawabannya tepat di tempat mata Anda sudah fokus.

  • (Sebagian) informasi itu dapat ditemukan dengan hanya menunggu tooltip untuk memunculkan variabel saya . Iya. Jika didukung, untuk beberapa jenis awalan, ketika kode Anda dikompilasi dengan bersih, setelah menunggu, Anda dapat membaca deskripsi dan menemukan informasi yang akan disampaikan oleh awalan secara instan. Saya merasa bahwa awalan adalah pendekatan yang lebih sederhana, lebih dapat diandalkan, dan lebih efisien.

  • "Ini lebih banyak mengetik" . Betulkah? Satu karakter lagi? Atau apakah itu - dengan alat penyelesaian otomatis IDE, ini akan sering mengurangi pengetikan, karena setiap karakter awalan mempersempit ruang pencarian secara signifikan. Tekan "e" dan tiga acara di kelas Anda muncul di intellisense. Tekan "c" dan lima konstanta terdaftar.

  • "Saya bisa menggunakan this->bukan m" . Ya, Anda bisa. Tapi itu hanya awalan yang jauh lebih jelek dan lebih verbose! Hanya saja ia membawa risiko yang jauh lebih besar (terutama dalam tim) karena bagi penyusunnya adalah opsional , dan karenanya penggunaannya sering tidak konsisten. mdi sisi lain singkat, jelas, eksplisit dan bukan opsional, jadi jauh lebih sulit untuk membuat kesalahan menggunakannya.

Jason Williams
sumber
6
Maksud saya, saya telah membaca bahwa masalah Notasi Hungarien hanya disebabkan oleh Simonyi yang disalahpahami. Dia menulis awalan harus digunakan untuk menunjukkan jenis variabel di mana dia berarti "ketik" seperti dalam "jenis hal" bukan tipe data literal. Kemudian orang-orang platform di Microsoft mengambilnya dan datang dengan lpsz ... dan sisanya adalah sejarah ...
VoidPointer
19
"Ini untuk statis" terdengar sangat mirip dengan bentuk "buruk" bahasa Hongaria bagi saya.
jalf
6
@Mehrdad: Saya pikir zini tidak sering berguna dalam bahasa seperti C ++ di mana detail implementasi tingkat rendah semacam itu harus dienkapsulasi di kelas, tetapi di C (di mana penghentian nol adalah perbedaan penting), saya setuju dengan Anda. IMO skema apa pun yang kami gunakan harus disesuaikan sebagaimana diperlukan agar sesuai dengan kebutuhan kami sendiri - Jadi, jika penghentian nol mempengaruhi penggunaan variabel Anda, tidak ada yang salah dengan menyatakan "z" sebagai awalan yang berguna.
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.Sepenuh hati saya tidak setuju. Jika saya menggunakan pointer yang salah, itu tidak akan dikompilasi ( void*mungkin pengecualian untuk pointer ganda) Dan seluruh ->lebih .cukup untuk memberitahu saya itu adalah pointer. Juga, jika Anda menggunakan pelengkapan otomatis, editor Anda mungkin memiliki tooltips deklarasi, menghilangkan kebutuhan untuk awalan untuk informasi variabel. Apapun, jawaban yang bagus.
Thomas Eding
5
Terpilih untuk penjelasan yang jelas, komprehensif dan menarik, namun ada sedikit di sini yang menyarankan bagaimana ini menghemat waktu dalam C ++ YET sebagian besar tetap tidak digunakan dalam banyak bahasa lain.
115

Saya biasanya tidak menggunakan awalan untuk variabel anggota.

Aku digunakan untuk menggunakan mawalan, sampai seseorang menunjukkan bahwa "C ++ sudah memiliki awalan standar untuk akses anggota: this->.

Jadi itulah yang saya gunakan sekarang. Yaitu, ketika ada ambiguitas , saya menambahkan this->awalan, tetapi biasanya, tidak ada ambiguitas, dan saya hanya bisa merujuk langsung ke nama variabel.

Bagi saya, itu yang terbaik dari kedua dunia. Saya memiliki awalan yang dapat saya gunakan ketika saya membutuhkannya, dan saya bebas untuk meninggalkannya kapan pun memungkinkan.

Tentu saja, penghitung yang jelas untuk ini adalah "ya, tetapi kemudian Anda tidak dapat melihat apakah variabel adalah anggota kelas atau tidak".

Yang saya katakan "jadi apa? Jika Anda perlu tahu itu, kelas Anda mungkin memiliki terlalu banyak negara. Atau fungsinya terlalu besar dan rumit".

Dalam praktiknya, saya menemukan bahwa ini bekerja dengan sangat baik. Sebagai bonus tambahan memungkinkan saya untuk mempromosikan variabel lokal ke anggota kelas (atau sebaliknya) dengan mudah, tanpa harus mengganti nama.

Dan yang terbaik, itu konsisten! Saya tidak perlu melakukan sesuatu yang istimewa atau mengingat konvensi apa pun untuk mempertahankan konsistensi.


Ngomong-ngomong, Anda tidak harus menggunakan garis bawah memimpin untuk anggota kelas Anda. Anda mendapatkan dekat dengan nama yang dicadangkan oleh implementasi.

Standar mencadangkan semua nama dimulai dengan garis bawah ganda atau garis bawah diikuti dengan huruf kapital. Itu juga menyimpan semua nama yang dimulai dengan satu garis bawah di namespace global .

Jadi anggota kelas dengan garis bawah utama diikuti dengan huruf kecil sah, tetapi cepat atau lambat Anda akan melakukan hal yang sama untuk pengenal dimulai dengan huruf besar, atau melanggar salah satu aturan di atas.

Jadi lebih mudah untuk menghindari garis bawah. Gunakan garis bawah postfix, atau awalan m_hanya mjika Anda ingin menyandikan lingkup dalam nama variabel.

jalf
sumber
"Jadi anggota kelas dengan garis bawah utama yang diikuti oleh huruf kecil adalah sah, tetapi cepat atau lambat Anda akan melakukan hal yang sama pada pengenal yang dimulai dengan huruf besar, atau jika tidak melanggar salah satu aturan di atas." - variabel anggota kelas tidak ada dalam ruang nama global, jadi garis bawah utama aman, terlepas dari apakah itu diikuti oleh huruf kecil atau huruf besar.
mbarnett
3
@ Mbarnett: Tidak, garis bawah diikuti oleh huruf besar disediakan secara umum , bukan hanya di namespace global.
jalf
9
terkejut bahwa suara jawaban ini kurang dari yang awalan.
Marson Mao
Saya setuju dengan jawaban ini, cukup gunakan this->jika Anda perlu menentukan bahwa itu adalah variabel anggota, atau tidak, itu bagus juga.
David Morton
Selain itu, Anda tidak perlu mendokumentasikan konvensi Anda untuk memberikan kode Anda kepada orang lain. Semua orang mengerti apa this->artinya.
Caduchon
34

Saya lebih suka menggarisbawahi postfix, seperti:

class Foo
{
   private:
      int bar_;

   public:
      int bar() { return bar_; }
};
jkeys
sumber
Saya juga. Saya juga memberi pengakses / mutator nama yang sama.
Rob
4
Menarik. Terlihat agak jelek pada awalnya, tapi saya bisa melihat bagaimana itu bisa bermanfaat.
ya23
6
Saya akan mengatakan itu jauh lebih jelek daripada: "mBar" atau "m_bar".
sydan
6
tetapi kemudian Anda miliki vector<int> v_;dan menulis v_.push_back(5)juga sangat jelek
avim
4
Itu gaya Google C ++.
Justme0
20

Akhir-akhir ini saya cenderung lebih memilih awalan m_ daripada tidak memiliki awalan sama sekali, alasannya tidak begitu penting untuk menandai variabel anggota, tetapi menghindari ambiguitas, katakan Anda memiliki kode seperti:

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

Sebab itu tidak berhasil, hanya satu yang foodiizinkan. Jadi pilihan Anda adalah:

  • this->foo = foo;

    Saya tidak suka, karena menyebabkan pembayaman parameter, Anda tidak lagi dapat menggunakan g++ -Wshadowperingatan, juga lebih lama untuk mengetik m_. Anda juga masih mengalami konflik penamaan antara variabel dan fungsi saat Anda memiliki a int foo;dan a int foo();.

  • foo = foo_; atau foo = arg_foo;

    Sudah menggunakan itu untuk sementara waktu, tetapi itu membuat daftar argumen jelek, dokumentasi seharusnya tidak berurusan dengan disambiguitas nama dalam implementasi. Konflik penamaan antara variabel dan fungsi juga ada di sini.

  • m_foo = foo;

    Dokumentasi API tetap bersih, Anda tidak mendapatkan ambiguitas antara fungsi dan variabel anggota dan lebih pendek untuk mengetiknya this->. Satu-satunya kelemahan adalah bahwa itu membuat struktur POD jelek, tetapi karena struktur POD tidak menderita ambiguitas nama, orang tidak perlu menggunakannya dengan mereka. Memiliki awalan yang unik juga membuat beberapa operasi pencarian & penggantian lebih mudah.

  • foo_ = foo;

    Sebagian besar keuntungan dari m_penerapan, tetapi saya menolaknya karena alasan estetika, garis bawah yang mengarah atau mengarah hanya membuat variabel terlihat tidak lengkap dan tidak seimbang. m_hanya terlihat lebih baik. Menggunakan m_juga lebih dapat diperpanjang, seperti yang dapat Anda gunakan g_untuk global dan s_statika.

PS: Alasan mengapa Anda tidak melihat m_di Python atau Ruby adalah karena kedua bahasa memberlakukan awalan mereka sendiri, Ruby menggunakan @untuk variabel anggota dan Python membutuhkan self..

Grumbel
sumber
1
Agar adil, Anda melewatkan setidaknya 2 opsi lain, misalnya (a) menggunakan nama lengkap seperti foohanya untuk anggota dan sebagai gantinya menggunakan huruf tunggal atau nama pendek untuk parameter atau penduduk lokal lainnya / throwaways, seperti int f; atau (b) awali parameter atau penduduk lokal lainnya dengan sesuatu. poin bagus kembali m_dan polong, meskipun; Saya telah secara mandiri sampai pada preferensi untuk mengikuti kedua pedoman itu, sebagian besar.
underscore_d
12

Saat membaca fungsi anggota, mengetahui siapa yang "memiliki" masing-masing variabel sangat penting untuk memahami makna variabel. Dalam fungsi seperti ini:

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

... cukup mudah untuk melihat dari mana apel dan pisang berasal, tetapi bagaimana dengan anggur, melon, dan kentang? Haruskah kita mencari di namespace global? Dalam deklarasi kelas? Apakah variabel anggota objek ini atau anggota kelas objek ini? Tanpa mengetahui jawaban untuk pertanyaan-pertanyaan ini, Anda tidak dapat memahami kode. Dan dalam fungsi yang lebih lama, bahkan deklarasi variabel lokal seperti apel dan pisang bisa tersesat dalam shuffle.

Mempertahankan label yang konsisten untuk global, variabel anggota, dan variabel anggota statis (mungkin masing-masing g_, m_, dan s_) langsung mengklarifikasi situasi.

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

Ini mungkin memerlukan waktu untuk membiasakan diri pada awalnya — tetapi kemudian, apa yang tidak ada dalam pemrograman? Ada hari ketika bahkan {dan} tampak aneh bagi Anda. Dan begitu Anda terbiasa dengan mereka, mereka membantu Anda memahami kode lebih cepat.

(Menggunakan "ini->" sebagai ganti m_ masuk akal, tetapi bahkan lebih bertele-tele dan secara visual mengganggu. Saya tidak melihatnya sebagai alternatif yang baik untuk menandai semua penggunaan variabel anggota.)

Kemungkinan keberatan terhadap argumen di atas adalah untuk memperluas argumen ke tipe. Mungkin juga benar bahwa mengetahui jenis variabel "sangat penting untuk memahami makna variabel." Jika demikian, mengapa tidak menambahkan awalan ke setiap nama variabel yang mengidentifikasi tipenya? Dengan logika itu, Anda berakhir dengan notasi Hongaria. Tetapi banyak orang menemukan notasi Hongaria melelahkan, jelek, dan tidak membantu.

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

Hongaria melakukannyaberi tahu kami sesuatu yang baru tentang kode tersebut. Kami sekarang memahami bahwa ada beberapa pemeran implisit dalam fungsi Foo :: bar (). Masalah dengan kode sekarang adalah bahwa nilai informasi yang ditambahkan oleh awalan Hongaria kecil relatif terhadap biaya visual. Sistem tipe C ++ mencakup banyak fitur untuk membantu tipe bekerja dengan baik bersama-sama atau untuk meningkatkan peringatan atau kesalahan kompiler. Kompiler membantu kita menangani tipe — kita tidak perlu notasi untuk melakukannya. Kita dapat menyimpulkan dengan cukup mudah bahwa variabel dalam Foo :: bar () mungkin numerik, dan jika hanya itu yang kita ketahui, itu cukup baik untuk mendapatkan pemahaman umum tentang fungsi tersebut. Oleh karena itu nilai mengetahui tipe tepat setiap variabel relatif rendah. Namun kejelekan dari variabel seperti "s_dSpuds" (atau bahkan hanya "dSpuds") sangat bagus. Begitu,

OldPeculier
sumber
Terima kasih atas ide s_. Tampaknya sangat berguna, dan entah bagaimana tidak pernah terpikir oleh saya.
Chris Olsen
10

Saya tidak bisa mengatakan seberapa lebar itu, tetapi berbicara secara pribadi, saya selalu (dan selalu) memberi awalan variabel anggota saya dengan 'm'. Misalnya:

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

Ini adalah satu-satunya bentuk awalan yang saya gunakan (saya sangat anti notasi Hungaria) tetapi telah memberikan saya manfaat yang bagus selama bertahun-tahun. Selain itu, saya biasanya membenci penggunaan garis bawah dalam nama (atau di mana pun dalam hal ini), tetapi membuat pengecualian untuk nama makro preprosesor, karena biasanya semua huruf besar.


sumber
5
Masalah dengan menggunakan m, daripada m_ (atau _) adalah dengan mode saat ini untuk camel case membuatnya sulit untuk membaca beberapa nama variabel.
Martin Beckett
1
@Neil aku bersamamu. @ mgb: Saya benci nama yang dimulai dengan '_' Ini hanya undangan untuk kesalahan di masa depan.
Martin York
1
@ Neil: Konvensi mana yang Anda gunakan, jika Anda tidak menggunakan garis bawah, dan tidak menggunakan camelcase?
jalf
2
Pemahaman saya adalah bahwa itu adalah camelCase yang membuat penggunaan hanya m untuk variabel seperti 'apData' membingungkan - itu menjadi 'mapData' daripada 'm_apData'. Saya menggunakan _camelCase untuk variabel anggota yang dilindungi / pribadi karena sangat menonjol
Martin Beckett
10
@ MartinBeckett: Anda harus memanfaatkan adalam skenario itu - Anda tidak melakukannya dengan benar. mApData( mawalan, maka nama variabelnya adalah apData).
Platinum Azure
8

Alasan utama untuk awalan anggota adalah untuk membedakan antara fungsi anggota lokal dan variabel anggota dengan nama yang sama. Ini berguna jika Anda menggunakan getter dengan nama benda itu.

Mempertimbangkan:

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_;
};

Variabel anggota tidak bisa disebut nama lengkap dalam kasus ini. Anda perlu mengubah nama fungsi anggota menjadi get_full_name () atau menghias variabel anggota entah bagaimana.

Serigala
sumber
1
Inilah alasan saya awalan. Saya pikir foo.name()ini jauh lebih mudah dibaca daripada foo.get_name()menurut saya.
Terrabits
6

Saya tidak berpikir satu sintaks memiliki nilai nyata di atas yang lain. Semuanya bermuara, seperti yang Anda sebutkan, untuk keseragaman di seluruh file sumber.

Satu-satunya titik di mana saya menemukan aturan seperti itu menarik adalah ketika saya membutuhkan 2 hal bernama identik, misalnya:

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

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

Saya menggunakannya untuk membedakan keduanya. Juga ketika saya membungkus panggilan, seperti dari windows Dll, RecvPacket (...) dari Dll mungkin dibungkus dalam RecvPacket (...) dalam kode saya. Dalam kesempatan khusus ini menggunakan awalan seperti "_" mungkin membuat keduanya mirip, mudah untuk mengidentifikasi yang mana, tetapi berbeda untuk kompiler

Eric
sumber
6

Beberapa tanggapan berfokus pada refactoring, bukan penamaan konvensi, sebagai cara untuk meningkatkan keterbacaan. Saya tidak merasa bahwa yang satu bisa menggantikan yang lain.

Saya kenal programmer yang tidak nyaman menggunakan deklarasi lokal; mereka lebih suka menempatkan semua deklarasi di atas blok (seperti dalam C), sehingga mereka tahu di mana menemukannya. Saya telah menemukan bahwa, di mana pelingkupan memungkinkan untuk itu, mendeklarasikan variabel tempat mereka pertama kali digunakan mengurangi waktu yang saya habiskan melirik ke belakang untuk menemukan deklarasi. (Ini berlaku bagi saya bahkan untuk fungsi kecil.) Itu membuatnya lebih mudah bagi saya untuk memahami kode yang saya lihat.

Saya harap ini cukup jelas bagaimana hubungannya dengan konvensi penamaan anggota: Ketika anggota diawali dengan seragam, saya tidak perlu melihat kembali sama sekali; Saya tahu deklarasi tidak akan ditemukan di file sumber.

Saya yakin bahwa saya tidak memulai lebih suka gaya ini. Namun seiring waktu, bekerja di lingkungan di mana mereka digunakan secara konsisten, saya mengoptimalkan pemikiran saya untuk mengambil keuntungan dari mereka. Saya pikir itu mungkin bahwa banyak orang yang saat ini merasa tidak nyaman dengan mereka juga akan lebih suka mereka, mengingat penggunaan yang konsisten.

Dan Breslau
sumber
5

Kebaktian itu hanya itu. Sebagian besar toko menggunakan konvensi kode untuk memudahkan pembacaan kode sehingga siapa pun dapat dengan mudah melihat sepotong kode dan dengan cepat menguraikan antara hal-hal seperti anggota publik dan pribadi.

Tuan Will
sumber
"antara hal-hal seperti anggota publik dan pribadi" - seberapa umumkah ini sebenarnya? saya tidak ingat melihatnya, tapi sekali lagi, saya tidak berkeliling meninjau basis kode atau apa pun.
underscore_d
Saya tidak melakukannya dalam pengkodean saya sendiri, tetapi saya telah bekerja di tempat-tempat di mana kami harus melakukannya berdasarkan panduan konvensi kode mereka. Saya lebih suka tidak melakukannya karena hampir semua IDE akan menampilkan variabel pribadi dengan warna yang berbeda.
Tn. Will
Hmm, saya kira itu hanya terjadi dalam situasi yang berbeda dari saya. Biasanya saya menggunakan salah satu classdari semua anggotanya yang adalah private/ protected, atau POD structsemua variabel yang public(dan sering juga const). Jadi, saya tidak perlu bertanya-tanya tentang tingkat akses anggota mana pun.
underscore_d
5

Yang lain mencoba memberlakukan menggunakan-> anggota ini setiap kali variabel anggota digunakan

Itu biasanya karena tidak ada awalan . Kompiler memerlukan informasi yang cukup untuk menyelesaikan variabel yang dipermasalahkan, baik itu nama yang unik karena awalan, atau melalui thiskata kunci.

Jadi, ya, saya pikir awalan masih berguna. Saya, misalnya, lebih suka mengetik '_' untuk mengakses anggota daripada 'ini->'.

Kent Boogaart
sumber
3
kompiler dapat menyelesaikannya ... variabel lokal akan menyembunyikan variabel yang memiliki cakupan lebih tinggi di sebagian besar bahasa. Ini untuk manfaat (meragukan) dari manusia yang membaca kode. Setiap IDE yang layak akan menyoroti penduduk lokal / anggota / global dengan cara yang berbeda sehingga tidak perlu untuk hal semacam ini
rmeador
1
Persis. Warga setempat akan menyembunyikan anggota kelas. Pertimbangkan konstruktor yang menetapkan anggota ini. Biasanya masuk akal untuk memberi nama parameter yang sama dengan anggota.
Kent Boogaart
6
Mengapa itu bau kode? Saya akan mengatakan itu sangat umum dan masuk akal, terutama ketika datang ke konstruktor.
Kent Boogaart
3
Konstruktor harus (umumnya) menetapkan penduduk lokal dalam daftar inisialisasi. Dan di sana, parameter tidak bayangan nama field, namun keduanya dapat diakses - sehingga Anda dapat menulisstruct Foo { int x; Foo(int x) : x(x) { ... } };
Pavel Minaev
2
Saya menganggap masalah dengan yang datang ketika Anda melakukannya, Foo(int x, bool blee) : x(x) { if (blee) x += bleecount; } // oops, forgot this->saya lebih suka memanggil variabel anggota saya sesuatu yang berguna dan kemudian memberikan parameter konstruktor yang cocok dengan mereka nama disingkat:Foo(int f) : foo(f) {...}
Steve Jessop
4

Bahasa lain akan menggunakan konvensi pengkodean, mereka cenderung berbeda. C # misalnya mungkin memiliki dua gaya yang berbeda yang cenderung digunakan orang, salah satu dari metode C ++ (_variable, mVariable atau awalan lain seperti notasi Hongaria), atau apa yang saya sebut sebagai metode StyleCop.

private int privateMember;
public int PublicMember;

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

Pada akhirnya, itu menjadi apa yang orang ketahui, dan apa yang terlihat terbaik. Saya pribadi berpikir kode lebih mudah dibaca tanpa notasi Hongaria, tetapi dapat menjadi lebih mudah untuk menemukan variabel dengan intellisense misalnya jika notasi Hungaria terpasang.

Dalam contoh saya di atas, Anda tidak memerlukan awalan m untuk variabel anggota karena awalan penggunaan Anda dengan ini. menunjukkan hal yang sama dalam metode yang dijalankan oleh compiler.

Ini tidak selalu berarti metode lain buruk, orang tetap berpegang pada apa yang berhasil.

Will Eddins
sumber
3

Ketika Anda memiliki metode besar atau blok kode, akan lebih mudah untuk mengetahui dengan segera jika Anda menggunakan variabel lokal atau anggota. itu untuk menghindari kesalahan dan untuk kejelasan yang lebih baik!

Matthieu
sumber
3
Jika Anda memiliki metode besar, untuk kejelasan yang lebih baik pilah.
sbi
4
Ada banyak alasan untuk tidak memecah beberapa metode besar. Misalnya, jika metode Anda perlu mempertahankan banyak status lokal, Anda harus memasukkan banyak parameter ke dalam metode bawahan Anda, membuat kelas baru yang ada hanya untuk tujuan meneruskan data antara metode ini, atau mendeklarasikan data status sebagai data anggota kelas induk. Semua ini memiliki masalah yang akan mempengaruhi kejelasan atau pemeliharaan metode, dibandingkan dengan metode panjang-ish tunggal (terutama yang logikanya langsung).
Steve Broberg
3
@sbi: Pedomannya hanya itu; pedoman, bukan aturan. Terkadang Anda membutuhkan metode besar yang tidak secara logis memungkinkan mereka untuk dipisahkan, dan kadang-kadang nama parameter berbenturan dengan anggota.
Ed S.
Tolong jangan membuat variabel anggota Anda menjadi publik. Cukup gunakan accessors. Tanda kurung harus memberi tahu pembaca bahwa itu adalah variabel anggota.
jkeys
Perhatikan bahwa ada peringatan dalam gcc (> = 4.6) untuk mendeteksi bentrokan nama:-Wshadow
Caduchon
3

IMO, ini pribadi. Saya tidak menempatkan awalan sama sekali. Lagi pula, jika kode dimaksudkan untuk umum, saya pikir itu harus lebih baik memiliki beberapa awalan, sehingga bisa lebih mudah dibaca.

Seringkali perusahaan besar menggunakan itu sendiri yang disebut 'aturan pengembang'.
Btw, yang terlucu namun paling cerdas yang saya lihat adalah KERING KISS (Jangan Ulangi Yourself. Keep It Simple, Stupid). :-)

Andrejs Cainikovs
sumber
3

Seperti yang sudah dikatakan orang lain, yang penting adalah bahasa sehari-hari (menyesuaikan gaya penamaan dan konvensi dengan basis kode di mana Anda menulis) dan konsisten.

Selama bertahun-tahun saya telah bekerja pada basis kode besar yang menggunakan kedua konvensi "ini->" serta menggunakan notasi garis bawah postfix untuk variabel anggota. Selama bertahun-tahun saya juga bekerja pada proyek yang lebih kecil, beberapa di antaranya tidak memiliki konvensi untuk penamaan variabel anggota, dan lainnya yang memiliki konvensi berbeda untuk penamaan variabel anggota. Dari proyek-proyek yang lebih kecil itu, saya secara konsisten menemukan bahwa yang tidak memiliki konvensi apa pun menjadi yang paling sulit untuk dilompati dengan cepat dan dipahami.

Saya sangat anal-retensive tentang penamaan. Saya akan menderita atas nama yang akan dianggap berasal dari kelas atau variabel ke titik bahwa, jika saya tidak dapat datang dengan sesuatu yang saya rasa "baik", saya akan memilih untuk menyebutkannya sesuatu yang tidak masuk akal dan memberikan komentar yang menggambarkan apa yang sebenarnya adalah. Dengan begitu, setidaknya namanya berarti persis apa yang saya maksud - tidak lebih dan tidak kurang. Dan sering, setelah menggunakannya sebentar, saya menemukan apa nama sebenarnya dan dapat kembali dan memodifikasi atau memperbaiki dengan tepat.

Satu poin terakhir pada topik IDE yang melakukan pekerjaan - itu semua bagus dan bagus, tetapi IDE sering tidak tersedia di lingkungan di mana saya telah melakukan pekerjaan yang paling mendesak. Terkadang satu-satunya yang tersedia pada saat itu adalah salinan 'vi'. Juga, saya telah melihat banyak kasus di mana penyelesaian kode IDE telah menyebarkan kebodohan seperti salah ejaan nama. Jadi, saya lebih suka tidak harus bergantung pada kruk IDE.

Chris Cleeland
sumber
3

Gagasan asli untuk awalan pada variabel anggota C ++ adalah untuk menyimpan informasi tipe tambahan yang tidak diketahui kompilator. Jadi misalnya, Anda bisa memiliki string yang memiliki panjang karakter tetap, dan lainnya yang variabel dan diakhiri dengan '\ 0'. Ke kompiler mereka berdua char *, tetapi jika Anda mencoba menyalin dari satu ke yang lain Anda mendapat masalah besar. Jadi, dari atas kepalaku,

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

di mana "asz" berarti variabel ini adalah "string ascii (nol-dihentikan) dan" arr "berarti variabel ini adalah array karakter.

Kemudian keajaiban terjadi. Kompiler akan sangat senang dengan pernyataan ini:

strcpy(arrWilma, aszFred);

Tetapi Anda, sebagai manusia, dapat melihatnya dan berkata "hei, variabel-variabel itu bukan tipe yang sama, saya tidak bisa melakukan itu".

Sayangnya banyak tempat menggunakan standar seperti "m_" untuk variabel anggota, "i" untuk bilangan bulat tidak peduli bagaimana digunakan, "cp" untuk pointer char. Dengan kata lain mereka menduplikasi apa yang diketahui kompiler, dan membuat kode sulit dibaca pada saat bersamaan. Saya percaya praktik jahat ini harus dilarang oleh undang-undang dan dikenakan hukuman berat.

Akhirnya, ada dua poin yang harus saya sebutkan:

  • Penggunaan fitur C ++ secara bijaksana memungkinkan kompiler mengetahui informasi yang harus Anda encode dalam variabel C-style mentah. Anda bisa membuat kelas yang hanya akan memungkinkan operasi yang valid. Ini harus dilakukan sama praktisnya.
  • Jika blok kode Anda begitu lama bahwa Anda lupa apa jenis variabel adalah sebelum Anda menggunakannya, mereka jalan terlalu panjang. Jangan gunakan nama, atur ulang.
AL Flanagan
sumber
Awalan yang menunjukkan jenis atau jenis variabel juga sesuatu yang layak didiskusikan, tetapi saya merujuk terutama pada awalan yang menunjukkan apakah sesuatu adalah anggota / bidang (pribadi). Notasi Hungaria terbalik yang Anda sebutkan bisa sangat berguna ketika diterapkan secara cerdas (seperti pada contoh Anda). Contoh favorit saya di mana masuk akal adalah koordinat relatif dan absolut. ketika Anda melihat absX = relX Anda dapat dengan jelas melihat bahwa ada sesuatu yang salah. Anda juga dapat menamai fungsi sesuai: absX = absFromRel (relX, offset);
VoidPointer
Catatan: inisialisasi aszFred dipertanyakan (menawarkan akses non-const ke string literal), dan inisialisasi arrWilma bahkan tidak dapat dikompilasi. (Anda mungkin bermaksud mendeklarasikan arrWilma sebagai sebuah array, bukan sebuah pointer!) Tidak masalah, ketika Anda menulis bahwa itu hanya di bagian atas kepala Anda ... :-)
Niels Dekker
Ups, Anda memang benar. Anak-anak, jangan mencobanya di rumah. Lakukan ini: 'const char * aszFred = "Hai, saya adalah string yang diakhiri dengan null"; char arrWilma [] = {'O', 'o', 'p', 's'}; '
AL Flanagan
3

Proyek kami selalu menggunakan "its" sebagai awalan untuk data anggota, dan "the" sebagai awalan untuk parameter, tanpa awalan untuk penduduk setempat. Ini sedikit imut, tetapi diadopsi oleh pengembang awal sistem kami karena mereka melihatnya digunakan sebagai konvensi oleh beberapa perpustakaan sumber komersial yang kami gunakan pada saat itu (baik XVT atau RogueWave - mungkin keduanya). Jadi, Anda akan mendapatkan sesuatu seperti ini:

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

Alasan utama yang saya lihat untuk pelingkupan awalan (dan tidak ada yang lain - Saya benci notasi Hungaria) adalah bahwa hal itu mencegah Anda dari mendapatkan masalah dengan menulis kode di mana Anda pikir Anda merujuk ke satu variabel, tetapi Anda benar-benar merujuk ke variabel lain dengan nama yang sama didefinisikan dalam lingkup lokal. Itu juga menghindari masalah datang dengan nama variabel untuk mewakili konsep yang sama, tetapi dengan cakupan yang berbeda, seperti contoh di atas. Jika demikian, Anda harus membuat awalan atau nama yang berbeda untuk parameter "theName" - mengapa tidak membuat aturan yang konsisten yang berlaku di mana-mana.

Hanya menggunakan ini-> tidak benar-benar cukup baik - kami tidak tertarik mengurangi ambiguitas seperti halnya kami dalam mengurangi kesalahan pengkodean, dan menyembunyikan nama dengan pengidentifikasi yang dicakup secara lokal bisa menyebalkan. Memang, beberapa kompiler mungkin memiliki opsi untuk menaikkan peringatan untuk kasus-kasus di mana Anda telah menutupi nama dalam cakupan yang lebih besar, tetapi peringatan itu dapat menjadi gangguan jika Anda bekerja dengan sejumlah besar perpustakaan pihak ketiga yang kebetulan telah memilih nama untuk variabel yang tidak digunakan yang sesekali bertabrakan dengan Anda.

Adapun yang / itu sendiri - saya jujur ​​menemukan lebih mudah untuk mengetik daripada menggarisbawahi (sebagai pengetik sentuh, saya menghindari menggarisbawahi bila memungkinkan - terlalu banyak membentang dari baris rumah), dan saya merasa lebih mudah dibaca daripada garis bawah misterius.

Steve Broberg
sumber
Ini adalah solusi paling intuitif dengan kurva belajar tercepat yang pernah saya dengar. Saya berharap bahasa yang diucapkan lebih fleksibel untuk menangani semua itu sehingga kita tidak perlu memikirkan tentang teknik-teknik baru untuk memecahkan ambiguitas dalam kode.
Guney Ozsan
2

Saya menggunakannya karena Intellisense VC ++ tidak dapat memberi tahu kapan harus menampilkan anggota pribadi ketika mengakses di luar kelas. Satu-satunya indikasi adalah simbol "kunci" kecil pada ikon bidang dalam daftar Intellisense. Itu hanya membuatnya lebih mudah untuk mengidentifikasi anggota pribadi (bidang) lebih mudah. Juga kebiasaan dari C # jujur.

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;
}
Zack
sumber
2

Saya pikir itu, jika Anda memerlukan awalan untuk membedakan anggota kelas dari parameter fungsi anggota dan variabel lokal, salah satu fungsinya terlalu besar atau variabel-variabelnya diberi nama buruk. Jika tidak pas di layar sehingga Anda dapat dengan mudah melihat apa itu, refactor.

Mengingat bahwa mereka sering dinyatakan jauh dari tempat mereka digunakan, saya menemukan bahwa konvensi penamaan untuk konstanta global (dan variabel global, meskipun IMO jarang ada kebutuhan untuk menggunakannya) masuk akal. Tetapi sebaliknya, saya tidak melihat banyak kebutuhan.

Yang mengatakan, saya biasa meletakkan garis bawah di akhir semua anggota kelas pribadi. Karena semua data saya bersifat pribadi, ini berarti anggota memiliki garis bawah garis belakang. Saya biasanya tidak melakukan ini lagi di basis kode baru, tetapi karena, sebagai programmer, Anda kebanyakan bekerja dengan kode lama, saya masih sering melakukan ini. Saya tidak yakin apakah toleransi saya terhadap kebiasaan ini berasal dari kenyataan bahwa saya selalu melakukan ini dan saya masih melakukannya secara teratur atau apakah itu benar-benar lebih masuk akal daripada menandai variabel anggota.

sbi
sumber
2
Ini sangat mencerminkan perasaan saya tentang masalah ini. Kode harus dapat dibaca tanpa menggunakan awalan. Mungkin kami tidak melihat banyak awalan yang digunakan dalam bahasa yang lebih modern karena komunitas pengguna mereka telah merangkul keterbacaan lebih dari apa yang kadang-kadang Anda lihat di C ++. Tentu saja, C ++ dapat dan harus dibaca. Hanya saja banyak C ++ yang tidak dapat dibaca telah ditulis selama bertahun-tahun.
VoidPointer
2

Dalam python, menggarisbawahi garis bawah ganda digunakan untuk meniru anggota pribadi. Untuk lebih jelasnya lihat jawaban ini

Konstantin Tenzin
sumber
1

Berguna untuk membedakan antara variabel anggota dan variabel lokal karena manajemen memori. Secara umum, variabel anggota yang dialokasikan heap harus dihancurkan di destructor, sementara variabel lokal yang dialokasikan heap harus dihancurkan dalam ruang lingkup itu. Menerapkan konvensi penamaan untuk variabel anggota memfasilitasi manajemen memori yang benar.

tukang minuman
sumber
bagaimana? Destructor tidak memiliki akses ke variabel lokal yang dideklarasikan dalam fungsi lain, jadi tidak ada ruang untuk kebingungan di sana. Selain itu, variabel lokal yang dialokasikan heap tidak boleh ada . Dan variabel anggota yang dialokasikan heap seharusnya hanya ada di dalam kelas RAII, cukup banyak.
jalf
"variabel lokal yang dialokasikan heap seharusnya tidak ada" agak kuat. Tetapi jika / ketika Anda menggunakannya, itu sangat penting untuk memastikan bahwa mereka dapat didelokasi dengan benar, sehingga konvensi penamaan yang disiplin untuk variabel anggota versus lokal sangat membantu memastikan hal ini.
frankster
1

Kode Lengkap merekomendasikan m_varname untuk variabel anggota.

Meskipun saya tidak pernah menganggap notasi berguna, saya akan memberikan bobot pendapat McConnell dalam membangun standar.

Paul Nathan
sumber
2
Tidak kecuali dia menjelaskan mengapa garis bawah. Saya penggemar berat bukunya "Pengembangan Cepat", yang telah saya rekomendasikan di sini berkali-kali, tetapi jauh lebih sedikit dari "Kode Lengkap" (yang saya akui saya belum membaca sejak pertama kali keluar).
1

Saya hampir tidak pernah menggunakan awalan di depan nama variabel saya. Jika Anda menggunakan IDE yang cukup layak, Anda harus dapat melakukan refactor dan menemukan referensi dengan mudah. Saya menggunakan nama yang sangat jelas dan tidak takut memiliki nama variabel yang panjang. Saya tidak pernah memiliki masalah dengan ruang lingkup baik dengan filosofi ini.

Satu-satunya waktu saya menggunakan awalan adalah pada baris tanda tangan. Saya akan awali parameter ke metode dengan _ jadi saya bisa memprogram defensif di sekitar mereka.

James
sumber
1

Anda seharusnya tidak memerlukan awalan seperti itu. Jika awalan semacam itu menawarkan keuntungan bagi Anda, gaya pengkodean Anda secara umum perlu diperbaiki, dan bukan awalan yang membuat kode Anda tidak jelas. Nama variabel buruk yang umum termasuk "lain" atau "2". Anda tidak memperbaikinya dengan mengharuskannya menjadi lebih, Anda memperbaikinya dengan membuat pengembang memikirkan apa yang dilakukan variabel itu di sana dalam konteks fungsi itu. Mungkin maksudnya remoteSide, atau newValue, atau secondTestListener atau sesuatu dalam lingkup itu.

Ini merupakan anakronisme yang efektif yang masih disebarkan terlalu jauh. Hentikan awalan variabel Anda dan beri mereka nama yang tepat yang kejelasannya mencerminkan berapa lama mereka digunakan. Hingga 5 baris Anda bisa menyebutnya "i" tanpa kebingungan; melebihi 50 baris Anda perlu nama yang cukup panjang.

omong kosong
sumber
1

Saya suka nama variabel untuk hanya memberi makna pada nilai-nilai yang dikandungnya, dan meninggalkan bagaimana mereka dinyatakan / diterapkan di luar nama. Saya ingin tahu apa arti nilainya, titik. Mungkin saya sudah melakukan lebih dari jumlah rata-rata refactoring, tetapi saya menemukan bahwa menanamkan bagaimana sesuatu diterapkan dalam nama membuat refactoring lebih membosankan daripada yang seharusnya. Awalan yang menunjukkan di mana atau bagaimana anggota objek dinyatakan spesifik implementasi.

color = Red;

Sebagian besar waktu, saya tidak peduli apakah Merah adalah enum, struct, atau apa pun, dan jika fungsinya sangat besar sehingga saya tidak dapat mengingat apakah warna dinyatakan secara lokal atau merupakan anggota, mungkin ini saatnya untuk istirahat. fungsi menjadi unit logis yang lebih kecil.

Jika kompleksitas siklomatik Anda begitu hebat sehingga Anda tidak dapat melacak apa yang terjadi dalam kode tanpa petunjuk khusus implementasi yang disematkan dalam nama-nama hal, kemungkinan besar Anda perlu mengurangi kompleksitas fungsi / metode Anda.

Sebagian besar, saya hanya menggunakan 'ini' dalam konstruktor dan inisialisasi.

ChrisG65
sumber
0

Saya menggunakan m_ untuk variabel anggota hanya untuk memanfaatkan Intellisense dan fungsi-IDE terkait. Ketika saya mengkode implementasi kelas saya bisa mengetik m_ dan melihat kotak kombo dengan semua anggota m_ dikelompokkan bersama.

Tapi aku bisa hidup tanpa masalah, tentu saja. Itu hanya gaya kerjaku.

Hernán
sumber
Anda juga bisa mengetikthis->
Roti panggang
0

Menurut JOINT STRIKE FIGHTER AIR VEHICLE C ++ CODING STANDAR (Desember 2005):

Aturan AV 67

Data publik dan yang dilindungi hanya boleh digunakan dalam struct — bukan kelas. Dasar Pemikiran: Kelas mampu mempertahankan invariannya dengan mengendalikan akses ke datanya. Namun, suatu kelas tidak dapat mengontrol akses ke anggota-anggotanya jika anggotanya non-pribadi. Karenanya semua data dalam kelas harus bersifat pribadi.

Dengan demikian, awalan "m" menjadi tidak berguna karena semua data harus pribadi.

Tapi itu kebiasaan yang baik untuk menggunakan awalan p sebelum pointer karena itu adalah variabel berbahaya.

Pierre-Louis Deschamps
sumber
0

Banyak dari kebaktian itu berasal dari zaman tanpa editor yang canggih. Saya akan merekomendasikan menggunakan IDE yang tepat yang memungkinkan Anda untuk mewarnai setiap jenis variabel. Warna jauh lebih mudah dikenali daripada awalan apa pun.

Jika Anda perlu mendapatkan lebih banyak detail pada variabel, setiap IDE modern harus dapat menunjukkannya kepada Anda dengan menggerakkan tanda sisipan atau kursor di atasnya. Dan jika Anda menggunakan variabel dengan cara yang salah (misalnya pointer dengan operator.), Anda akan mendapatkan kesalahan.

Elias Mueller
sumber