เหตุใดจึงใช้ส่วนนำหน้ากับตัวแปรสมาชิกในคลาส C ++


150

รหัส C ++ จำนวนมากใช้ระเบียบการสร้างประโยคเพื่อทำเครื่องหมายตัวแปรสมาชิก ตัวอย่างทั่วไป ได้แก่

  • m_ memberNameสำหรับสมาชิกสาธารณะ (ที่สมาชิกสาธารณะถูกนำมาใช้เลย)
  • _ memberNameสำหรับสมาชิกส่วนตัวหรือสมาชิกทั้งหมด

คนอื่นพยายามบังคับใช้สมาชิกนี้ - > เมื่อใดก็ตามที่มีการใช้ตัวแปรสมาชิก

จากประสบการณ์ของฉันฐานรหัสขนาดใหญ่ส่วนใหญ่ล้มเหลวในการใช้กฎดังกล่าวอย่างสม่ำเสมอ

ในภาษาอื่น ๆ อนุสัญญาเหล่านี้แพร่หลายน้อยกว่ามาก ฉันเห็นมันเป็นครั้งคราวเท่านั้นใน Java หรือรหัส C # ฉันคิดว่าฉันไม่เคยเห็นมันในรหัส Ruby หรือ Python ดังนั้นดูเหมือนว่าจะมีแนวโน้มด้วยภาษาที่ทันสมัยกว่าที่จะไม่ใช้มาร์กอัปพิเศษสำหรับตัวแปรสมาชิก

อนุสัญญานี้ยังคงมีประโยชน์ทุกวันนี้ใน C ++ หรือว่าเป็นเพียงความผิดสมัย โดยเฉพาะอย่างยิ่งมันถูกใช้อย่างไม่สอดคล้องกันทั่วทั้งห้องสมุด ภาษาอื่น ๆ ที่แสดงให้เห็นว่าสามารถทำได้โดยไม่ต้องนำหน้าสมาชิก?


15
ฉันชอบมัน ในรหัสที่ซับซ้อนมันเป็นสิ่งสำคัญที่จะต้องรู้ว่า vars ใดบ้างที่เป็นของท้องถิ่นและไม่ใช่ ฉันมักจะใช้คำนำหน้ามากกว่าการบังคับ this-> ซึ่งผมพบว่าจะมีจำนวนมากของการพิมพ์พิเศษและตัวเลือก (ในขณะที่การตั้งชื่อจะบังคับให้คุณทำมัน)
โจ

5
คุณไม่เคยเห็นมาก่อนใน Ruby เนื่องจากมี @ สำหรับแอตทริบิวต์และเป็นสำนวนของการสร้าง accessors ที่ต้องการใช้คุณลักษณะโดยตรง
Steve Jessop

6
ตามPEP 8ตัวแปรสมาชิกที่ไม่ใช่แบบสาธารณะจะถูกนำหน้าด้วยการขีดเส้นใต้ในหลาม (ตัวอย่าง: self._something = 1)
นาธานออสมัน

2
ไม่ควรใช้การเน้นไวยากรณ์ของโปรแกรมแก้ไขเพื่อระบุสิ่งเหล่านี้
เกินไป

2
คุณเคยเห็นเทียบเท่าthis->memberในรหัสหลาม โดยทั่วไปแล้วในภาษาไพ ธ อนมันself.memberไม่ได้เป็นเพียงแค่การประชุม แต่เป็นภาษาที่ต้องการ
matec

คำตอบ:


48

คุณต้องระวังด้วยการใช้เครื่องหมายขีดเส้นใต้ ขีดเส้นใต้นำหน้าตัวอักษรใหญ่ในคำสงวนไว้ ตัวอย่างเช่น:

_Foo

_L

เป็นคำที่สงวนไว้ทั้งหมดในขณะที่

_foo

_L

ไม่ใช่ มีสถานการณ์อื่น ๆ ที่ไม่อนุญาตให้ขีดเส้นใต้ก่อนตัวอักษรตัวเล็ก ในกรณีเฉพาะของฉันฉันพบว่า _L นั้นถูกสงวนไว้โดย Visual C ++ 2005 และการปะทะกันสร้างผลลัพธ์ที่ไม่คาดคิด

ฉันอยู่บนรั้วว่ามีประโยชน์อย่างไรในการทำเครื่องหมายตัวแปรท้องถิ่น

นี่คือลิงค์เกี่ยวกับตัวระบุที่สงวนไว้: อะไรคือกฎเกี่ยวกับการใช้ขีดล่างในตัวระบุ C ++


4
ที่จริงแล้วทั้ง _foo และ _l สงวนไว้ที่ขอบเขตเนมสเปซ

13
แต่พวกเขาก็โอเคในฐานะชื่อตัวแปรสมาชิก ฉันไม่ได้นำหน้าขีดเส้นใต้เพราะกฎนั้นสับสนเกินไปและฉันก็ถูกไฟไหม้ในอดีต
34490 Juan Juan

11
คำเหล่านี้ไม่ใช่คำสงวน พวกเขาเป็นชื่อที่สงวนไว้ หากเป็นคำที่สงวนไว้คุณจะไม่สามารถใช้คำเหล่านั้นได้เลย เนื่องจากเป็นชื่อที่สงวนไว้คุณสามารถใช้งานได้ แต่เป็นความเสี่ยงของคุณเอง
TonyK

235

ฉันทั้งหมดในความโปรดปรานของคำนำหน้าทำดี

ฉันคิดว่า (ระบบ) สัญกรณ์ฮังการีรับผิดชอบส่วนใหญ่ของ "การลงโทษที่ไม่ดี" ที่คำนำหน้าได้รับ

สัญกรณ์นี้ส่วนใหญ่ไม่มีจุดหมายในภาษาที่พิมพ์อย่างรุนแรงเช่นใน C ++ "lpsz" เพื่อบอกคุณว่าสตริงของคุณเป็นตัวชี้ที่ยาวไปยังสตริงที่ถูกยกเลิก nul เมื่อ:: เซกเมนต์สถาปัตยกรรมเป็นประวัติศาสตร์โบราณ, สตริง C ++ เป็นตัวชี้การประชุมทั่วไป อาร์เรย์ char และมันก็ไม่ใช่เรื่องยากที่จะรู้ว่า "customerName" เป็นสตริง!

อย่างไรก็ตามฉันใช้คำนำหน้าเพื่อระบุการใช้งานของตัวแปร (เป็นหลัก "Apps Hungarian" ถึงแม้ว่าฉันต้องการหลีกเลี่ยงคำศัพท์ภาษาฮังการีเนื่องจากมีความสัมพันธ์ที่ไม่ดีและไม่เป็นธรรมกับ System Hungarian) และนี่เป็นการประหยัดเวลาและสะดวกมากวิธีการลดข้อผิดพลาด

ฉันใช้:

  • m สำหรับสมาชิก
  • c สำหรับค่าคงที่ / อ่านได้อย่างเดียว
  • p สำหรับตัวชี้ (และ pp สำหรับตัวชี้ไปยังตัวชี้)
  • v สำหรับความผันผวน
  • s สำหรับคงที่
  • i สำหรับดัชนีและตัววนซ้ำ
  • e สำหรับกิจกรรม

ฉันต้องการที่จะให้ชนิดที่ชัดเจนผมใช้คำต่อท้ายมาตรฐาน (เช่นรายการ ComboBox ฯลฯ )

สิ่งนี้ทำให้โปรแกรมเมอร์ตระหนักถึงการใช้งานของตัวแปรเมื่อใดก็ตามที่พวกเขาเห็น / ใช้มัน เนื้อหาที่สำคัญที่สุดคือ "p" สำหรับตัวชี้ (เนื่องจากการเปลี่ยนแปลงการใช้งานจาก var. เป็น var-> และคุณต้องระมัดระวังให้มากขึ้นด้วยตัวชี้ - NULLs, ตัวชี้ทางคณิตศาสตร์เป็นต้น) แต่สิ่งอื่น ๆ นั้นมีประโยชน์มาก

ตัวอย่างเช่นคุณสามารถใช้ชื่อตัวแปรเดียวกันได้หลายวิธีในฟังก์ชั่นเดียว: (นี่คือตัวอย่าง C ++ แต่ใช้ได้กับหลายภาษาเท่า ๆ กัน)

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

คุณสามารถดูที่นี่:

  • ไม่มีความสับสนระหว่างสมาชิกและพารามิเตอร์
  • ไม่มีความสับสนระหว่างดัชนี / ตัววนซ้ำกับรายการ
  • ใช้ชุดของตัวแปรที่เกี่ยวข้องอย่างชัดเจน (รายการไอเท็มตัวชี้และดัชนี) ที่หลีกเลี่ยงการผิดพลาดของชื่อทั่วไป (คลุมเครือ) เช่น "count", "index"
  • คำนำหน้าลดการพิมพ์ (สั้นลงและทำงานได้ดีกว่าเมื่อเติมข้อมูลอัตโนมัติ) ดีกว่าตัวเลือกอื่น ๆ เช่น "itemIndex" และ "itemPtr"

อีกจุดที่ยอดเยี่ยมของตัววนซ้ำ "iName" คือฉันไม่เคยทำดัชนีอาร์เรย์ด้วยดัชนีที่ไม่ถูกต้องและถ้าฉันคัดลอกวนรอบในวงอื่นฉันไม่ต้องปรับโครงสร้างตัวแปรดัชนีวงใดวงหนึ่ง

เปรียบเทียบตัวอย่างง่ายๆที่ไม่สมจริงนี้:

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

(ซึ่งยากต่อการอ่านและมักจะนำไปสู่การใช้ "i" โดยที่ "j" ตั้งใจไว้)

ด้วย:

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

(ซึ่งสามารถอ่านได้มากขึ้นและขจัดความสับสนทั้งหมดในการจัดทำดัชนีด้วยการทำให้สมบูรณ์อัตโนมัติใน IDEs ที่ทันสมัยสิ่งนี้ยังรวดเร็วและง่ายต่อการพิมพ์)

ประโยชน์ต่อไปคือตัวอย่างโค้ดไม่ต้องการบริบทใด ๆเข้าใจฉันสามารถคัดลอกโค้ดสองบรรทัดไปยังอีเมลหรือเอกสารและใครก็ตามที่อ่านว่าข้อมูลโค้ดสามารถบอกความแตกต่างระหว่างสมาชิกทุกคนค่าคงที่ตัวชี้ดัชนีดัชนี ฯลฯ ฉันไม่ต้องเพิ่ม "โอ้และระวังเพราะ 'data' เป็นตัวชี้ไปยังตัวชี้ "เนื่องจากเรียกว่า 'ppData'

และด้วยเหตุผลเดียวกันฉันไม่ต้องละสายตาจากโค้ดเพื่อทำความเข้าใจ ฉันไม่ต้องค้นหารหัสเพื่อค้นหาว่า 'ข้อมูล' เป็นพารามิเตอร์พารามิเตอร์สมาชิกหรือค่าคงที่ในท้องถิ่นหรือไม่ ฉันไม่ต้องขยับมือของฉันไปที่เมาส์เพื่อให้ฉันสามารถเลื่อนตัวชี้ไปที่ 'data' แล้วรอคำแนะนำเครื่องมือ (ซึ่งบางครั้งก็ไม่เคยปรากฏ) มาปรากฏขึ้น ดังนั้นโปรแกรมเมอร์จึงสามารถอ่านและเข้าใจรหัสได้เร็วขึ้นอย่างมากเพราะพวกเขาไม่ต้องเสียเวลาค้นหาขึ้นและลงหรือรอ

(ถ้าคุณไม่คิดว่าคุณจะเสียเวลาค้นหาสิ่งที่ต้องทำออกมาให้ค้นหาโค้ดที่คุณเขียนเมื่อปีที่แล้วและยังไม่ได้ดูเลยเปิดไฟล์แล้วกระโดดลงครึ่งหนึ่งโดยไม่อ่าน ตอนนี้คุณสามารถอ่านจากจุดนี้ก่อนที่คุณจะไม่รู้ว่ามีบางสิ่งบางอย่างที่เป็นสมาชิกพารามิเตอร์หรือท้องถิ่นตอนนี้ข้ามไปยังตำแหน่งสุ่มอื่น ... นี่คือสิ่งที่เราทุกคนทำตลอดทั้งวันเมื่อเราก้าวผ่านรหัสของคนอื่น หรือพยายามที่จะเข้าใจวิธีการเรียกฟังก์ชั่นของพวกเขา)

คำนำหน้า 'm' ยังหลีกเลี่ยงสัญลักษณ์ (IMHO) ที่น่าเกลียดและใช้คำว่า "this->" และความไม่ลงรอยกันที่รับประกันได้ (แม้ว่าคุณจะระมัดระวังคุณก็มักจะมีส่วนผสมของ 'this-> data' และ 'data' ในคลาสเดียวกันเนื่องจากไม่มีสิ่งใดบังคับใช้การสะกดชื่อที่สอดคล้องกัน)

สัญกรณ์ 'นี้' มีจุดประสงค์เพื่อแก้ไขความกำกวม - แต่ทำไมทุกคนจะจงใจเขียนโค้ดที่คลุมเครือ? ความกำกวมจะนำไปสู่ข้อผิดพลาดไม่ช้าก็เร็ว และในบางภาษา 'นี่' ไม่สามารถใช้สำหรับสมาชิกแบบสแตติกได้ดังนั้นคุณต้องแนะนำ 'กรณีพิเศษ' ในรูปแบบการเข้ารหัสของคุณ ฉันชอบที่จะมีกฎการเข้ารหัสที่เรียบง่ายเพียงข้อเดียวที่ใช้กับทุกที่ - ชัดเจนชัดเจนและสอดคล้องกัน

ประโยชน์ที่สำคัญสุดท้ายคือ Intellisense และการทำให้สมบูรณ์อัตโนมัติ ลองใช้ Intellisense ในแบบฟอร์ม Windows เพื่อค้นหาเหตุการณ์ - คุณต้องเลื่อนวิธีการเรียนพื้นฐานลึกลับหลายร้อยรายการที่คุณไม่จำเป็นต้องโทรหาเพื่อค้นหาเหตุการณ์ แต่ถ้าทุกเหตุการณ์มีคำนำหน้า "e" เหตุการณ์เหล่านั้นจะปรากฏในกลุ่มภายใต้ "e" โดยอัตโนมัติ ดังนั้นคำนำหน้าใช้เพื่อจัดกลุ่มสมาชิก const เหตุการณ์และอื่น ๆ ในรายการ intellisense ทำให้การค้นหาชื่อที่คุณต้องการรวดเร็วและง่ายขึ้น (โดยปกติวิธีอาจมีค่าประมาณ 20-50 (locals, params, สมาชิก, const, เหตุการณ์) ที่สามารถเข้าถึงได้ในขอบเขตของมัน แต่หลังจากพิมพ์คำนำหน้า (ฉันต้องการใช้ดัชนีตอนนี้ดังนั้นฉันพิมพ์ 'i .. ') ฉันมีตัวเลือกที่สมบูรณ์แบบอัตโนมัติเพียง 2-5 ตัว' การพิมพ์พิเศษ '

ฉันเป็นโปรแกรมเมอร์ขี้เกียจและการประชุมข้างต้นช่วยฉันได้มาก ฉันสามารถเขียนโค้ดได้เร็วขึ้นและทำผิดพลาดน้อยลงเพราะฉันรู้ว่าควรใช้ตัวแปรทุกตัวอย่างไร


มีปากเสียงกับ

ดังนั้นข้อเสียคืออะไร? ข้อโต้แย้งทั่วไปกับคำนำหน้าคือ:

  • "แผนการคำนำหน้าไม่ดี / ชั่ว" ฉันยอมรับว่า "m_lpsz" และตระกูลของมันมีคุณภาพต่ำและไร้ประโยชน์ทั้งหมด นั่นเป็นเหตุผลที่ฉันแนะนำให้ใช้สัญลักษณ์ที่ออกแบบมาอย่างดีซึ่งออกแบบมาเพื่อรองรับความต้องการของคุณแทนที่จะคัดลอกสิ่งที่ไม่เหมาะสมกับบริบทของคุณ (ใช้เครื่องมือที่เหมาะสมสำหรับงาน)

  • "ถ้าฉันจะเปลี่ยนการใช้งานของบางสิ่งบางอย่างที่ผมต้องเปลี่ยนชื่อมันว่า" ใช่แน่นอนคุณต้องทำนั่นคือสิ่งที่ต้องทำการรีบูทและทำไม IDEs ถึงมีเครื่องมือการรีแฟคเตอร์เพื่อทำงานนี้อย่างรวดเร็วและไม่เจ็บปวด แม้จะไม่มีคำนำหน้าการเปลี่ยนการใช้งานของตัวแปรเกือบแน่นอนหมายความว่าชื่อของมันควรจะเปลี่ยน

  • "คำนำหน้าเพียงแค่สร้างความสับสนให้ฉัน" เช่นเดียวกับทุกเครื่องมือจนกว่าคุณจะเรียนรู้วิธีใช้ เมื่อสมองของคุณคุ้นเคยกับรูปแบบการตั้งชื่อแล้วมันจะกรองข้อมูลออกโดยอัตโนมัติและคุณจะไม่คิดว่าคำนำหน้านั้นจะมีอีกต่อไป แต่คุณต้องใช้รูปแบบเช่นนี้อย่างสมบูรณ์เป็นเวลาหนึ่งหรือสองสัปดาห์ก่อนที่คุณจะกลายเป็น "คล่องแคล่ว" จริงๆ และนั่นคือเมื่อผู้คนจำนวนมากดูที่โค้ดเก่าและเริ่มสงสัยว่าพวกเขาจัดการได้อย่างไรโดยไม่มีโครงร่างที่ดี

  • "ผมก็สามารถดูรหัสที่จะทำงานสิ่งนี้ออก" ใช่ แต่คุณไม่จำเป็นต้องเสียเวลาดูที่อื่นในรหัสหรือจดจำทุกรายละเอียดของมันเมื่อคำตอบอยู่ตรงจุดที่ตาของคุณเพ่งความสนใจไปแล้ว

  • (บางคน) ที่สามารถพบได้โดยเพียงแค่รอให้คำแนะนำเครื่องมือที่จะปรากฏขึ้นบนตัวแปรของฉัน ใช่. หากรองรับคำนำหน้าบางประเภทเมื่อโค้ดของคุณรวบรวมได้อย่างสมบูรณ์หลังจากรอคุณสามารถอ่านคำอธิบายและค้นหาข้อมูลที่คำนำหน้าจะถ่ายทอดได้ทันที ฉันรู้สึกว่าคำนำหน้าเป็นวิธีที่ง่ายกว่าเชื่อถือได้และมีประสิทธิภาพมากกว่า

  • "มันเป็นเรื่องการพิมพ์มากขึ้น" จริงๆ? ตัวละครทั้งหมดมากกว่าหนึ่งตัว? หรือเป็น - ด้วยเครื่องมือเติมข้อมูลอัตโนมัติของ IDE มันมักจะลดการพิมพ์เนื่องจากอักขระนำหน้าแต่ละตัวจะ จำกัด พื้นที่การค้นหาให้แคบลงอย่างมาก กด "e" และเหตุการณ์ทั้งสามในชั้นเรียนของคุณจะปรากฏขึ้นในระบบ Intellisense กด "c" และค่าคงที่ห้ารายการ

  • "ผมสามารถใช้this->แทนm " ก็ใช่คุณทำได้ แต่นั่นเป็นเพียงคำนำหน้าที่น่าเกลียดมากและละเอียดมากขึ้น! มีเพียงความเสี่ยงที่ยิ่งใหญ่กว่า (โดยเฉพาะในทีม) เพราะคอมไพเลอร์เป็นตัวเลือกและการใช้งานจึงไม่สอดคล้องกันบ่อยครั้ง mในทางกลับกันสั้นชัดเจนชัดเจนและไม่จำเป็นดังนั้นจึงเป็นเรื่องยากมากที่จะทำผิดพลาดโดยใช้มัน


6
ฉันหมายถึงได้อ่านว่าปัญหาเกี่ยวกับสัญกรณ์ฮังกาเรนนั้นเกิดจากการเข้าใจผิดของซิโมนี่ เขาเขียนคำนำหน้าควรใช้เพื่อระบุประเภทของตัวแปรที่เขาหมายถึง "ประเภท" เหมือนใน "ชนิดของสิ่ง" ไม่ใช่ประเภทข้อมูลตามตัวอักษร ต่อมาพวกแพลตฟอร์มที่ไมโครซอฟท์หยิบมันขึ้นมาและมาพร้อมกับ lpsz ... และส่วนที่เหลือคือประวัติศาสตร์ ...
VoidPointer

19
"s สำหรับเสียงคงที่" สวยมากเหมือน "ฮังการี" ในรูปแบบของฉัน
jalf

6
@ Mehrdad: ฉันไม่คิดว่าzมักจะมีประโยชน์มากในภาษาอย่าง C ++ โดยที่รายละเอียดการใช้งานระดับต่ำนั้นควรถูกห่อหุ้มในชั้นเรียน แต่ใน C (โดยที่การยุติศูนย์เป็นสิ่งที่สำคัญ) ฉันเห็นด้วยกับคุณ IMO แบบแผนใด ๆ ที่เราใช้ควรปรับให้เหมาะกับความต้องการของเราเองดังนั้นถ้าการยกเลิกแบบไม่ส่งผลกระทบต่อการใช้งานตัวแปรนั้นไม่มีอะไรผิดปกติที่การประกาศ "z" เป็นคำเสริมหน้าที่มีประโยชน์
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.ฉันไม่เห็นด้วยอย่างสุดใจ ถ้าฉันใช้ตัวชี้ผิดมันก็จะไม่รวบรวม ( void*อาจเป็นข้อยกเว้นสำหรับตัวชี้คู่) และทั้ง->กว่า.จะเพียงพอที่จะบอกฉันมันเป็นตัวชี้ นอกจากนี้หากคุณใช้การเติมข้อความอัตโนมัติเครื่องมือแก้ไขของคุณอาจมีคำแนะนำเครื่องมือการประกาศทำให้ไม่จำเป็นต้องใส่คำนำหน้าสำหรับข้อมูลตัวแปร โดยไม่คำนึงถึงคำตอบที่ดี
Thomas Eding

5
เพิ่มขึ้นสำหรับคำอธิบายที่ชัดเจนครอบคลุมและน่าสนใจ แต่มีเพียงเล็กน้อยที่นี่แนะนำว่าวิธีนี้ช่วยประหยัดเวลาใน C ++ YET ยังคงไม่ได้ใช้ในภาษาอื่น ๆ เป็นจำนวนมาก

115

ฉันมักจะไม่ใช้คำนำหน้าสำหรับตัวแปรสมาชิก

ผมเคยใช้mคำนำหน้าจนกว่าจะมีคนชี้ให้เห็นว่า "C ++ this->แล้วมีคำนำหน้ามาตรฐานสำหรับการเข้าถึงสมาชิก:

นั่นคือสิ่งที่ฉันใช้ตอนนี้ นั่นคือเมื่อมีความกำกวมฉันจะเพิ่มthis->คำนำหน้า แต่โดยปกติไม่มีความกำกวมอยู่และฉันสามารถอ้างถึงชื่อตัวแปรโดยตรง

สำหรับฉันนั่นเป็นสิ่งที่ดีที่สุดของทั้งสองโลก ฉันมีคำนำหน้าฉันสามารถใช้เมื่อฉันต้องการมันและฉันมีอิสระที่จะปล่อยมันเมื่อใดก็ตามที่เป็นไปได้

แน่นอนว่าตัวนับที่ชัดเจนของเรื่องนี้คือ "ใช่ แต่คุณไม่สามารถมองเห็นได้อย่างรวดเร็วว่าตัวแปรเป็นสมาชิกในชั้นเรียนหรือไม่"

ที่ฉันพูดว่า "แล้วไงถ้าคุณจำเป็นต้องรู้ว่าชั้นของคุณอาจมีสถานะมากเกินไปหรือฟังก์ชั่นใหญ่เกินไปและซับซ้อน"

ในทางปฏิบัติฉันพบว่ามันใช้งานได้ดีมาก ในฐานะโบนัสที่เพิ่มเข้ามามันทำให้ฉันสามารถโปรโมตตัวแปรท้องถิ่นให้กับสมาชิกในคลาส (หรือวิธีอื่น ๆ ) ได้อย่างง่ายดายโดยไม่ต้องเปลี่ยนชื่อ

และที่สำคัญที่สุดมันก็สอดคล้องกัน! ฉันไม่ต้องทำอะไรเป็นพิเศษหรือจำอนุสัญญาใด ๆ เพื่อรักษาความมั่นคง


โดยวิธีการที่คุณไม่ควรใช้ขีดเส้นใต้ชั้นนำสำหรับสมาชิกชั้นเรียนของคุณ คุณจะอึดอัดกับชื่อที่สงวนไว้โดยการนำไปใช้งาน

มาตรฐานขอสงวนชื่อทั้งหมดที่เริ่มต้นด้วยเครื่องหมายขีดล่างหรือขีดล่างคู่ตามด้วยตัวพิมพ์ใหญ่ นอกจากนี้ยังขอสงวนชื่อทั้งหมดที่เริ่มต้นด้วยการขีดเดียวใน namespace

สมาชิกชั้นเรียนที่มีเครื่องหมายขีดล่างนำหน้าตามด้วยตัวอักษรตัวพิมพ์เล็กจึงถูกกฎหมาย แต่ไม่ช้าก็เร็วคุณจะต้องทำเช่นเดียวกันกับตัวระบุที่ขึ้นต้นด้วยตัวพิมพ์ใหญ่หรือแตกกฎข้อใดข้อหนึ่งข้างต้น

ดังนั้นง่ายกว่าที่จะหลีกเลี่ยงการขีดเส้นใต้ ใช้ขีดล่างของ postfix หรือ a m_หรือเพียงmนำหน้าหากคุณต้องการเข้ารหัสขอบเขตในชื่อตัวแปร


"สมาชิกชั้นเรียนที่มีเครื่องหมายขีดเส้นใต้นำหน้าตามด้วยตัวอักษรตัวพิมพ์เล็กเป็นเรื่องถูกกฎหมาย แต่ไม่ช้าก็เร็วคุณจะต้องทำเช่นเดียวกันกับตัวระบุที่ขึ้นต้นด้วยตัวพิมพ์ใหญ่หรือแตกกฎข้อใดข้อหนึ่งข้างต้น" - ตัวแปรสมาชิกระดับไม่ได้อยู่ในเนมสเปซส่วนกลางดังนั้นขีดเส้นใต้ชั้นนำจึงปลอดภัยไม่ว่าจะตามด้วยตัวอักษรตัวล่างหรือตัวพิมพ์ใหญ่
mbarnett

3
@mbarnett: ไม่ขีดล่างตามด้วยตัวพิมพ์ใหญ่ถูกจองโดยทั่วไปไม่ใช่เฉพาะในเนมสเปซส่วนกลาง
jalf

9
แปลกใจที่การโหวตของคำตอบนี้น้อยกว่าคำนำหน้า
Marson Mao

ฉันเห็นด้วยกับคำตอบนี้ใช้this->ถ้าคุณต้องการระบุว่าเป็นตัวแปรสมาชิกหรือไม่ก็ทำได้ดีเช่นกัน
David Morton

ยิ่งกว่านั้นคุณไม่ต้องจัดทำเอกสารการประชุมเพื่อให้รหัสแก่คนอื่น ทุกคนเข้าใจความthis->หมาย
Caduchon

34

ฉันชอบขีดล่างของ postfix เช่น:

class Foo
{
   private:
      int bar_;

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

ฉันด้วย. ฉันยังให้ชื่อเดียวกันกับ accessors / mutators
Rob

4
น่าสนใจ ดูเล็กน้อยน่าเกลียดในตอนแรก แต่ฉันสามารถดูว่ามันจะมีประโยชน์
ya23

6
ฉันจะบอกว่ามันน่าเกลียดน้อยกว่ามาก: "mBar" หรือ "m_bar"
sydan

6
แต่แล้วคุณก็มีvector<int> v_;และการเขียนv_.push_back(5)ก็น่าเกลียดเกินไป
avim

4
นั่นคือสไตล์ Google C ++
Justme0

20

เมื่อเร็ว ๆ นี้ฉันมีแนวโน้มที่จะชอบคำนำหน้า m_ แทนที่จะไม่มีคำนำหน้าเลยเหตุผลไม่มากที่สำคัญในการตั้งค่าสถานะตัวแปรสมาชิก แต่มันหลีกเลี่ยงความคลุมเครือกล่าวว่าคุณมีรหัสเช่น:

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

สาเหตุนั้นไม่ได้ผลfooอนุญาตเพียงหนึ่งอย่างเท่านั้น ดังนั้นทางเลือกของคุณคือ:

  • this->foo = foo;

    ฉันไม่ชอบเพราะทำให้เกิดเงาพารามิเตอร์คุณไม่สามารถใช้อีกต่อไป g++ -Wshadowm_คำเตือนยังอีกต่อไปที่จะพิมพ์แล้ว นอกจากนี้คุณยังคงทำงานในการตั้งชื่อขัดแย้งระหว่างตัวแปรและฟังก์ชั่นเมื่อคุณมีและint foo;int foo();

  • foo = foo_; หรือ foo = arg_foo;

    เคยใช้สิ่งนั้นมาระยะหนึ่งแล้ว แต่มันทำให้ข้อโต้แย้งแสดงรายการที่น่าเกลียดเอกสารไม่ควรเกี่ยวข้องกับความไม่ลงรอยกันของชื่อในการนำไปใช้ การตั้งชื่อความขัดแย้งระหว่างตัวแปรและฟังก์ชั่นยังมีอยู่ที่นี่

  • m_foo = foo;

    เอกสาร API อยู่ที่สะอาด, this->คุณไม่ได้รับความคลุมเครือระหว่างสมาชิกฟังก์ชันและตัวแปรและสั้นลงพิมพ์แล้ว ข้อเสียเปรียบเพียงอย่างเดียวคือมันทำให้โครงสร้าง POD น่าเกลียด แต่เนื่องจากโครงสร้าง POD ไม่ได้รับผลกระทบจากความคลุมเครือของชื่อในตอนแรกจึงไม่จำเป็นต้องใช้มันกับพวกเขา การมีส่วนนำหน้าที่ไม่ซ้ำใครยังช่วยให้การค้นหาและแทนที่ทำได้ง่ายขึ้น

  • foo_ = foo;

    ข้อดีของการm_ใช้งานส่วนใหญ่แต่ฉันปฏิเสธด้วยเหตุผลด้านสุนทรียภาพการลากหรือขีดเส้นใต้นำทำให้ตัวแปรดูไม่สมบูรณ์และไม่สมดุล m_แค่ดูดีกว่า การใช้m_ยังสามารถขยายได้มากขึ้นตามที่คุณสามารถใช้g_สำหรับกลมและs_สถิตยศาสตร์

PS: เหตุผลที่คุณไม่เห็นm_ในหลามหรือทับทิมเป็นเพราะทั้งสองภาษาบังคับใช้คำนำหน้าตัวเองทับทิมใช้@สำหรับตัวแปรสมาชิกและ Python self.ต้อง


1
เพื่อความเป็นธรรมคุณพลาดอย่างน้อย 2 ตัวเลือกอื่น ๆ เช่น (a) ใช้ชื่อเต็มเช่นfooเฉพาะสำหรับสมาชิกและแทนที่จะใช้ชื่อตัวอักษรเดียวหรือชื่อย่อสำหรับพารามิเตอร์หรือคนในท้องถิ่น / คนอื่น ๆ เช่นint f; หรือ (b) ใส่คำนำหน้าพารามิเตอร์หรือคนในท้องถิ่นอื่นด้วยบางสิ่ง จุดดีm_และพ็อดใหม่ ฉันได้มาถึงการตั้งค่าเพื่อปฏิบัติตามแนวทางทั้งสองอย่างเป็นอิสระส่วนใหญ่
underscore_d

12

เมื่ออ่านผ่านฟังก์ชั่นสมาชิกการรู้ว่าใคร "เจ้าของ" ตัวแปรแต่ละตัวเป็นสิ่งจำเป็นอย่างยิ่งในการทำความเข้าใจความหมายของตัวแปร ในฟังก์ชั่นเช่นนี้:

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

... มันง่ายพอที่จะดูว่าแอปเปิ้ลและกล้วยมาจากไหน แต่องุ่นแตงโมและดอกตูมล่ะ เราควรดูใน namespace ทั่วโลกหรือไม่ ในการประกาศคลาส? ตัวแปรเป็นสมาชิกของวัตถุนี้หรือเป็นสมาชิกของคลาสของวัตถุนี้หรือไม่? หากไม่ทราบคำตอบสำหรับคำถามเหล่านี้คุณจะไม่สามารถเข้าใจรหัสได้ และในฟังก์ชั่นที่ยาวนานยิ่งขึ้นการประกาศตัวแปรในท้องถิ่นเช่นแอปเปิ้ลและกล้วยก็สามารถสูญหายได้ในการสับเปลี่ยน

การจัดเตรียมเลเบลที่สอดคล้องกันสำหรับ globals ตัวแปรสมาชิกและตัวแปรสมาชิกแบบสแตติก (อาจ g_, m_ และ s_ ตามลำดับ) ชี้แจงสถานการณ์โดยทันที

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

สิ่งเหล่านี้อาจทำให้เกิดความคุ้นเคยในตอนแรก - แต่แล้วในการเขียนโปรแกรมอะไรไม่ได้ มีวันหนึ่งที่แม้แต่ {และ} ก็ดูประหลาดกับคุณ และเมื่อคุณชินกับมันแล้วพวกเขาจะช่วยให้คุณเข้าใจรหัสได้เร็วขึ้น

(การใช้ "this->" แทน m_ สมเหตุสมผล แต่ยิ่งยืดยาวและก่อกวนสายตามากขึ้นฉันไม่เห็นว่าเป็นทางเลือกที่ดีในการทำเครื่องหมายการใช้ตัวแปรสมาชิกทั้งหมด)

การคัดค้านที่เป็นไปได้ของอาร์กิวเมนต์ข้างต้นคือการขยายอาร์กิวเมนต์เป็นประเภท มันอาจเป็นความจริงด้วยว่าการรู้ชนิดของตัวแปร "จำเป็นอย่างยิ่งต่อการเข้าใจความหมายของตัวแปร" หากเป็นเช่นนั้นทำไมไม่เพิ่มคำนำหน้าให้กับชื่อตัวแปรแต่ละตัวที่ระบุประเภทของมัน ด้วยตรรกะนั้นคุณจะได้สัญกรณ์ฮังการี แต่หลายคนพบว่าสัญกรณ์ฮังการีทำงานหนักน่าเกลียดและไร้ประโยชน์

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

ฮังการี ไม่บอกอะไรเราใหม่เกี่ยวกับรหัส ตอนนี้เราเข้าใจว่ามีการปลดเปลื้องโดยนัยหลายประการในฟังก์ชั่น Foo :: bar () ปัญหาของรหัสในขณะนี้คือมูลค่าของข้อมูลที่เพิ่มโดยคำนำหน้าฮังการีมีขนาดเล็กเมื่อเทียบกับค่าใช้จ่ายภาพ ระบบประเภท C ++ มีคุณสมบัติมากมายที่จะช่วยให้ประเภททำงานร่วมกันได้ดีหรือเพื่อเพิ่มคำเตือนคอมไพเลอร์หรือข้อผิดพลาด คอมไพเลอร์ช่วยเราจัดการกับประเภทต่างๆ - เราไม่จำเป็นต้องมีเครื่องหมายเพื่อทำเช่นนั้น เราสามารถอนุมานได้ง่ายว่าตัวแปรใน Foo :: bar () อาจเป็นตัวเลขและถ้านั่นคือทั้งหมดที่เรารู้ว่ามันดีพอสำหรับการทำความเข้าใจทั่วไปของฟังก์ชัน ดังนั้นคุณค่าของการรู้ประเภทของตัวแปรแต่ละตัวจึงค่อนข้างต่ำ แต่ความอัปลักษณ์ของตัวแปรเช่น "s_dSpuds" (หรือแม้แต่ "dSpuds") นั้นยอดเยี่ยม ดังนั้น,


ขอบคุณสำหรับแนวคิด s_ ดูเหมือนว่ามีประโยชน์มากและไม่เคยเกิดขึ้นกับฉัน
Chris Olsen

10

ฉันไม่สามารถพูดได้ว่ามันเป็นอย่างไรในการแสดงความคิดเห็น แต่การพูดเป็นการส่วนตัวฉันมักจะ (และมีเสมอ) นำหน้าตัวแปรสมาชิกของฉันด้วย 'm' เช่น:

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

มันเป็นรูปแบบเดียวของคำนำหน้าฉันใช้ (ฉันต่อต้านสัญกรณ์ฮังการีมาก) แต่มันทำให้ฉันรู้สึกดีตลอดหลายปีที่ผ่านมา นอกจากนี้ฉันมักจะเกลียดการใช้เครื่องหมายขีดล่างในชื่อ (หรือที่อื่นใดก็ตามสำหรับเรื่องนั้น) แต่ทำข้อยกเว้นสำหรับชื่อแมโครตัวประมวลผลล่วงหน้าเนื่องจากมักจะเป็นตัวพิมพ์ใหญ่ทั้งหมด


5
ปัญหาเกี่ยวกับการใช้ m แทนที่จะเป็น m_ (หรือ _) เป็นปัญหาปัจจุบันสำหรับกรณีอูฐทำให้อ่านชื่อตัวแปรบางตัวได้ยาก
มาร์ติน Beckett

1
@ Neil ฉันอยู่กับคุณ @mgb: ฉันเกลียดชื่อที่ขึ้นต้นด้วย '_' มันเป็นแค่คำเชิญสำหรับสิ่งที่ผิดพลาดในอนาคต
Martin York

1
@ Neil: คุณใช้การประชุมแบบไหนถ้าคุณไม่ใช้ขีดเส้นใต้และไม่ใช้ camelcase?
jalf

2
ความเข้าใจของฉันคือว่ามันเป็น camelCase ซึ่งทำให้การใช้เพียงแค่ m สำหรับตัวแปรเช่น 'apData' ทำให้เกิดความสับสน - มันกลายเป็น 'mapData' แทนที่จะเป็น 'm_apData' ผมใช้ _camelCase สำหรับตัวแปรการคุ้มครองสมาชิก / ส่วนตัวเพราะมันยืนออก
มาร์ติน Beckett

10
@MartinBeckett: คุณควรใช้ประโยชน์aในสถานการณ์นั้น - คุณไม่ได้ทำถูกต้อง mApData( mคำนำหน้าชื่อตัวแปรคือapData)
Platinum Azure

8

เหตุผลหลักสำหรับคำนำหน้าสมาชิกคือการแยกความแตกต่างระหว่างฟังก์ชั่นสมาชิกท้องถิ่นและตัวแปรสมาชิกที่มีชื่อเดียวกัน สิ่งนี้มีประโยชน์ถ้าคุณใช้ getters ด้วยชื่อของสิ่งของ

พิจารณา:

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

ตัวแปรสมาชิกไม่สามารถเรียกว่า full_name ในกรณีนี้ คุณต้องเปลี่ยนชื่อฟังก์ชั่นสมาชิกเป็น get_full_name () หรือตกแต่งตัวแปรสมาชิกอย่างใด


1
นี่คือเหตุผลที่ฉันนำหน้า ฉันคิดว่าfoo.name()สามารถอ่านได้มากกว่าfoo.get_name()ความคิดของฉัน
Terrabits

6

ฉันไม่คิดว่าไวยากรณ์หนึ่งมีค่าจริงมากกว่าอีก ทุกอย่างจะลดลงอย่างที่คุณพูดถึงเพื่อให้เกิดความเท่าเทียมในไฟล์ต้นฉบับ

จุดเดียวที่ฉันพบกฎดังกล่าวที่น่าสนใจคือเมื่อฉันต้องการ 2 สิ่งที่ชื่อเหมือนกันตัวอย่างเช่น:

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

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

ฉันใช้มันเพื่อแยกความแตกต่างทั้งสอง นอกจากนี้เมื่อฉันตัดสายเช่นจาก windows Dll, RecvPacket (... )จาก Dll อาจถูกห่อในRecvPacket (... )ในรหัสของฉัน ในโอกาสพิเศษเหล่านี้โดยใช้คำนำหน้าเช่น "_" อาจทำให้ทั้งสองดูเหมือนกันง่ายต่อการระบุว่าเป็นที่ใด แต่แตกต่างกันสำหรับคอมไพเลอร์


6

คำตอบบางอย่างมุ่งเน้นไปที่การปรับโครงสร้างใหม่มากกว่าการตั้งชื่อแบบแผนเพื่อปรับปรุงความสามารถในการอ่าน ฉันไม่รู้สึกว่าจะสามารถแทนที่คนอื่น

ฉันรู้จักโปรแกรมเมอร์ที่ไม่สบายใจในการใช้การประกาศในท้องที่ พวกเขาชอบที่จะวางประกาศทั้งหมดที่ด้านบนของบล็อก (เช่นใน C) ดังนั้นพวกเขารู้ว่าจะหาได้ที่ไหน ฉันได้พบว่าการกำหนดขอบเขตอนุญาตให้ทำได้การประกาศตัวแปรที่พวกเขาใช้งานครั้งแรกจะลดเวลาที่ฉันใช้มองไปด้านหลังเพื่อค้นหาการประกาศ (สิ่งนี้เป็นจริงสำหรับฉันแม้สำหรับฟังก์ชั่นเล็ก ๆ ) ที่ทำให้ฉันเข้าใจรหัสที่ฉันกำลังดูได้ง่ายขึ้น

ฉันหวังว่ามันชัดเจนเพียงพอว่าสิ่งนี้เกี่ยวข้องกับการตั้งชื่อสมาชิก: เมื่อสมาชิกมีคำนำหน้าอย่างสม่ำเสมอฉันไม่ต้องมองกลับเลย ฉันรู้ว่าการประกาศจะไม่พบแม้แต่ในไฟล์ต้นฉบับ

ฉันแน่ใจว่าฉันไม่ได้เริ่มชอบสไตล์เหล่านี้ เมื่อเวลาผ่านไปการทำงานในสภาพแวดล้อมที่พวกเขาใช้อย่างสม่ำเสมอฉันปรับความคิดของฉันเพื่อใช้ประโยชน์จากพวกเขา ฉันคิดว่าเป็นไปได้ที่คนจำนวนมากที่รู้สึกอึดอัดกับพวกเขาในขณะนี้ก็จะชอบพวกเขาด้วยการใช้งานที่สม่ำเสมอ


5

การประชุมเหล่านั้นเป็นเพียงแค่นั้น ร้านค้าส่วนใหญ่ใช้ระเบียบรหัสเพื่อลดความซับซ้อนในการอ่านรหัสเพื่อให้ทุกคนสามารถดูรหัสได้อย่างง่ายดายและถอดรหัสระหว่างสิ่งต่าง ๆ เช่นสมาชิกสาธารณะและส่วนตัวได้อย่างรวดเร็ว


"ระหว่างสิ่งต่าง ๆ เช่นสมาชิกของรัฐและเอกชน" - สิ่งนี้เป็นเรื่องธรรมดาจริง ๆ ? ฉันจำไม่ได้ว่าเห็นมัน แต่จากนั้นอีกครั้งฉันจะไม่ทบทวนโค้ดเบสหรืออะไรอีก
underscore_d

ฉันไม่ได้ทำมันในการเขียนโค้ดของตัวเอง แต่ฉันได้ทำงานในสถานที่ที่เราต้องทำตามคู่มือการประชุมรหัสของพวกเขา ฉันไม่ต้องการทำเพราะ IDE เกือบทั้งหมดจะแสดงตัวแปรส่วนตัวเป็นสีที่แตกต่างกัน
นายวิลล์

อืมฉันคิดว่ามันจะเกิดขึ้นในสถานการณ์ที่แตกต่างจากของฉันเท่านั้น ปกติฉันจะใช้ทั้งclassสมาชิกทั้งหมดที่มีprivate/ protectedหรือ POD structซึ่งตัวแปรทั้งหมดเป็นpublic(และบ่อยครั้งconst) ดังนั้นฉันไม่จำเป็นต้องสงสัยเกี่ยวกับระดับการเข้าถึงของสมาชิกที่ได้รับ
underscore_d

5

คนอื่นพยายามบังคับใช้สมาชิกนี้ -> เมื่อใดก็ตามที่มีการใช้ตัวแปรสมาชิก

ที่มักจะเป็นเพราะไม่มีคำนำหน้า คอมไพเลอร์ต้องการข้อมูลที่เพียงพอเพื่อแก้ไขตัวแปรที่เป็นปัญหาไม่ว่าจะเป็นชื่อที่ไม่ซ้ำกันเพราะเป็นส่วนนำหน้าหรือผ่านทางthisคำสำคัญ

ใช่ฉันคิดว่าคำนำหน้ายังคงมีประโยชน์ สำหรับฉันหนึ่งคนต้องการพิมพ์ '_' เพื่อเข้าถึงสมาชิกมากกว่า 'this->'


3
คอมไพเลอร์สามารถแก้ไขปัญหาได้ ... ตัวแปรในตัวเครื่องจะซ่อนตัวในขอบเขตที่สูงกว่าในภาษาส่วนใหญ่ มันเป็นเพื่อประโยชน์ (พิรุธ) ของมนุษย์อ่านรหัส ใด ๆ IDE ดีจะเน้นชาวบ้าน / สมาชิก / Globals ในรูปแบบที่แตกต่างกันจึงมีความจำเป็นในการจัดเรียงของสิ่งนี้ไม่มี
rmeador

1
เผง ชาวบ้านจะซ่อนสมาชิกชั้นเรียน พิจารณาตัวสร้างที่ตั้งสมาชิกเหล่านี้ โดยปกติแล้วจะสมเหตุสมผลที่จะตั้งชื่อพารามิเตอร์เหมือนกับสมาชิก
Kent Boogaart

6
ทำไมรหัสถึงมีกลิ่น ฉันจะบอกว่ามันเป็นเรื่องธรรมดาและสมเหตุสมผลโดยเฉพาะอย่างยิ่งเมื่อพูดถึงผู้รับเหมา
Kent Boogaart

3
คอนสตรัคควร (โดยทั่วไป) ตั้งค่าท้องถิ่นในรายการเริ่มต้น และที่นั่นพารามิเตอร์ไม่ใช่ชื่อเขตข้อมูลเงา แต่ทั้งคู่สามารถเข้าถึงได้ดังนั้นคุณจึงสามารถเขียนได้struct 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->ฉันชอบที่จะเรียกฉันสิ่งที่ตัวแปรสมาชิกที่มีประโยชน์และพารามิเตอร์แล้วให้สร้างที่ตรงกับพวกเขาย่อชื่อ:Foo(int f) : foo(f) {...}
สตีฟเจสซอพ

4

ภาษาอื่น ๆ จะใช้วิธีการเข้ารหัสพวกเขามีแนวโน้มที่จะแตกต่างกัน ตัวอย่างเช่น C # อาจมีสองสไตล์ที่แตกต่างกันซึ่งผู้คนมักจะใช้ไม่ว่าจะเป็นหนึ่งในเมธอด C ++ (_variable, mVariable หรือส่วนนำหน้าอื่น ๆ เช่นสัญกรณ์ฮังการี) หรือสิ่งที่ฉันอ้างถึงเป็นวิธี StyleCop

private int privateMember;
public int PublicMember;

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

ในที่สุดมันก็กลายเป็นสิ่งที่ผู้คนรู้และสิ่งที่ดูดีที่สุด ฉันเองคิดว่ารหัสสามารถอ่านได้มากขึ้นโดยไม่ต้องใช้สัญกรณ์ฮังการี แต่มันจะง่ายขึ้นในการค้นหาตัวแปรที่มีการใช้ระบบ Intellisense เช่นถ้ามีการแนบสัญกรณ์ฮังการี

ในตัวอย่างข้างต้นคุณไม่จำเป็นต้องมีคำนำหน้า m สำหรับตัวแปรสมาชิกเนื่องจากคำนำหน้าใช้กับสิ่งนี้ บ่งบอกถึงสิ่งเดียวกันในวิธีการคอมไพเลอร์บังคับใช้

ไม่ได้หมายความว่าวิธีการอื่น ๆ ไม่ดีผู้คนยึดติดกับสิ่งที่ได้ผล


3

เมื่อคุณมีเมธอดหรือบล็อคโค้ดขนาดใหญ่จะสะดวกที่จะรู้ได้ทันทีถ้าคุณใช้ตัวแปรโลคัลหรือสมาชิก เพื่อหลีกเลี่ยงข้อผิดพลาดและเพื่อความชัดเจนที่ดีกว่า!


3
หากคุณมีวิธีการขนาดใหญ่เพื่อความชัดเจนที่ดีขึ้น
sbi

4
มีเหตุผลมากมายที่จะไม่ทำลายวิธีการที่สำคัญบางอย่าง ตัวอย่างเช่นหากวิธีการของคุณต้องการรักษาสถานะท้องถิ่นจำนวนมากคุณต้องส่งพารามิเตอร์จำนวนมากไปยังวิธีการย่อยสร้างคลาสใหม่ที่มีเพียงเพื่อจุดประสงค์ในการส่งข้อมูลระหว่างวิธีการเหล่านี้หรือประกาศข้อมูลสถานะเป็น ข้อมูลสมาชิกของคลาสพาเรนต์ ทั้งหมดนี้มีปัญหาที่จะส่งผลกระทบต่อความชัดเจนหรือความสามารถในการบำรุงรักษาของวิธีเปรียบเทียบกับวิธี long-ish (โดยเฉพาะอย่างยิ่งตรรกะที่ตรงไปตรงมา)
Steve Broberg

3
@sbi: แนวทางเป็นเช่นนั้น หลักเกณฑ์ไม่ใช่กฎ บางครั้งคุณต้องมีวิธีการขนาดใหญ่ที่ไม่ได้มีเหตุผลในการแยกออกจากกันและบางครั้งชื่อพารามิเตอร์ขัดแย้งกับสมาชิก
Ed S.

โปรดอย่าทำให้ตัวแปรสมาชิกของคุณเป็นแบบสาธารณะ เพียงใช้อุปกรณ์เสริม วงเล็บควรบอกผู้อ่านว่าเป็นตัวแปรสมาชิก
jkeys

โปรดทราบว่ามีคำเตือนใน gcc (> = 4.6) เพื่อตรวจสอบการปะทะกันของชื่อ:-Wshadow
Caduchon

3

IMO นี่เป็นเรื่องส่วนตัว ฉันไม่ได้ใส่คำนำหน้าใด ๆ เลย อย่างไรก็ตามถ้ารหัสมีความหมายต่อสาธารณะฉันคิดว่าควรมีคำนำหน้าดีกว่าเพื่อให้สามารถอ่านได้มากขึ้น

บ่อยครั้งที่ บริษัท ขนาดใหญ่กำลังใช้งานตัวเองเรียกว่า 'กฎของนักพัฒนาซอฟต์แวร์'
Btw คนที่ตลกที่สุดและฉลาดที่สุดที่ฉันเคยเห็นคือ DRY KISS (อย่าทำซ้ำตัวเอง Keep It Simple, Stupid) :-)


3

ดังที่คนอื่นพูดไปแล้วสิ่งสำคัญคือต้องเป็นภาษาพูด (ปรับรูปแบบการตั้งชื่อและอนุสัญญาให้ตรงกับรหัสฐานที่คุณเขียน) และให้สอดคล้องกัน

เป็นเวลาหลายปีที่ฉันได้ทำงานกับฐานรหัสขนาดใหญ่ที่ใช้ทั้งการประชุม "this->" เช่นเดียวกับการใช้postfixเครื่องหมายขีดล่างขีดสำหรับตัวแปรสมาชิก ตลอดหลายปีที่ผ่านมาฉันได้ทำงานในโครงการขนาดเล็กซึ่งบางโครงการก็ไม่มีระเบียบแบบแผนสำหรับการตั้งชื่อตัวแปรสมาชิกและอื่น ๆ ที่มีแบบแผนที่แตกต่างกันสำหรับการตั้งชื่อตัวแปรสมาชิก ในบรรดาโครงการขนาดเล็กเหล่านั้นฉันพบว่าคนเหล่านั้นที่ขาดการประชุมเป็นสิ่งที่ยากที่สุดที่จะกระโดดเข้าและเข้าใจได้อย่างรวดเร็ว

ฉันไม่ค่อยแน่ใจเรื่องการตั้งชื่อ ฉันจะทนทุกข์ทรมานกับชื่อที่จะกำหนดให้กับชั้นเรียนหรือตัวแปรจนถึงจุดที่ถ้าฉันไม่สามารถเกิดขึ้นกับสิ่งที่ฉันรู้สึกว่า "ดี" ฉันจะเลือกที่จะตั้งชื่อมันเป็นเรื่องไร้สาระและให้ความคิดเห็นอธิบายสิ่งที่มันจริง ๆ คือ. ด้วยวิธีนี้อย่างน้อยชื่อก็หมายถึงสิ่งที่ฉันตั้งใจจะให้หมายถึง - ไม่มีอะไรมากและไม่มีอะไรน้อยลง และบ่อยครั้งที่หลังจากใช้ไปสักพักหนึ่งฉันค้นพบว่าชื่อควรเป็นอะไรจริงๆและสามารถย้อนกลับไปแก้ไขหรือปรับเปลี่ยนใหม่ได้อย่างเหมาะสม

ประเด็นสุดท้ายหนึ่งในหัวข้อของ IDE ที่ใช้ในการทำงาน - นั่นคือทั้งหมดที่ดีและดี แต่ IDEs มักจะไม่สามารถใช้ได้ในสภาพแวดล้อมที่ฉันได้ทำงานเร่งด่วนที่สุด บางครั้งสิ่งเดียวที่มีให้ ณ จุดนั้นคือสำเนาของ 'vi' นอกจากนี้ฉันเคยเห็นหลายกรณีที่การเติมโค้ด IDE ได้ทำให้เกิดความโง่เช่นการสะกดชื่อไม่ถูกต้อง ดังนั้นฉันไม่ต้องการพึ่ง IDE crutch


3

แนวคิดดั้งเดิมสำหรับคำนำหน้าบนตัวแปรสมาชิก C ++ คือการเก็บข้อมูลประเภทเพิ่มเติมที่คอมไพเลอร์ไม่ทราบ ตัวอย่างเช่นคุณอาจมีสตริงที่มีความยาวคงที่ของตัวอักษรและอีกอันเป็นตัวแปรและถูกยกเลิกด้วย '\ 0' ไปยังคอมไพเลอร์พวกเขาทั้งคู่char *แต่ถ้าคุณพยายามที่จะคัดลอกจากที่หนึ่งไปยังอีกที่คุณได้รับปัญหาใหญ่ ดังนั้นปิดส่วนหัวของฉัน

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

โดยที่ "asz" หมายถึงตัวแปรนี้คือ "ascii string (zero-terminated) และ" arr "หมายถึงตัวแปรนี้เป็นอาร์เรย์อักขระ

จากนั้นเวทมนต์ก็เกิดขึ้น คอมไพเลอร์จะมีความสุขอย่างสมบูรณ์แบบกับคำสั่งนี้:

strcpy(arrWilma, aszFred);

แต่คุณในฐานะมนุษย์สามารถมองดูและพูดว่า "เฮ้ตัวแปรเหล่านั้นไม่เหมือนกันจริง ๆ ฉันไม่สามารถทำอย่างนั้นได้"

น่าเสียดายที่หลาย ๆ แห่งใช้มาตรฐานเช่น "m_" สำหรับตัวแปรสมาชิก "i" สำหรับจำนวนเต็มไม่ว่าจะใช้วิธีใด "cp" สำหรับพอยน์เตอร์ถ่าน ในคำอื่น ๆ ที่พวกเขากำลังทำซ้ำสิ่งที่คอมไพเลอร์รู้และทำให้รหัสยากที่จะอ่านในเวลาเดียวกัน ฉันเชื่อว่าการกระทำที่เป็นอันตรายนี้ควรผิดกฎหมายโดยต้องได้รับโทษที่รุนแรง

ในที่สุดมีสองจุดที่ฉันควรพูดถึง:

  • การใช้คุณสมบัติ C ++ อย่างรอบคอบช่วยให้ผู้รวบรวมทราบข้อมูลที่คุณต้องเข้ารหัสในตัวแปรแบบ C ดิบ คุณสามารถสร้างคลาสที่จะอนุญาตการดำเนินการที่ถูกต้องเท่านั้น สิ่งนี้ควรกระทำให้มากที่สุด
  • หากบล็อกรหัสของคุณตราบใดที่คุณลืมสิ่งที่พิมพ์ตัวแปรคือก่อนที่คุณจะใช้มันพวกเขามีวิธีที่ยาวเกินไป อย่าใช้ชื่อจัดระเบียบใหม่

คำนำหน้าที่ระบุประเภทหรือชนิดของตัวแปรเป็นสิ่งที่ควรค่าแก่การพูดคุย แต่ส่วนใหญ่ฉันหมายถึงคำนำหน้าเพื่อระบุว่าบางสิ่งเป็นสมาชิก / ฟิลด์ (ส่วนตัว) สัญกรณ์ฮังการีแบบย้อนกลับที่คุณพูดถึงนั้นค่อนข้างมีประโยชน์เมื่อใช้อย่างชาญฉลาด (เช่นในตัวอย่างของคุณ) ตัวอย่างที่ฉันชอบซึ่งทำให้เข้าใจได้คือพิกัดสัมพัทธ์และพิกัดสัมบูรณ์ เมื่อคุณเห็น absX = relX คุณสามารถเห็นได้ชัดว่ามีบางอย่างที่ผิดพลาดนอกจากนี้คุณยังสามารถตั้งชื่อฟังก์ชันตาม: absX = absFromRel (relX, offset);
VoidPointer

หมายเหตุ: การกำหนดค่าเริ่มต้นของ aszFred เป็นปัญหา (ให้การเข้าถึงแบบไม่ใช่ const เพื่อสตริงตัวอักษร) และการเริ่มต้นของ arrWilma จะไม่ได้รวบรวม (คุณอาจจะตั้งใจที่จะประกาศ arrWilma เป็นอาร์เรย์แทนตัวชี้!) ไม่มีปัญหา แต่เป็นคุณเขียนว่ามันเป็นเพียงแค่ปิดด้านบนของหัวของคุณ ... :-)
นีลส์ Dekker

โอ๊ะคุณพูดถูก เด็ก ๆ อย่าลองทำที่บ้าน ทำสิ่งนี้: 'const char * aszFred = "สวัสดีฉันเป็นสตริงที่สิ้นสุดด้วยค่า null"; char arrWilma [] = {'O', 'o', 'p', 's'}; '
อัลฟลานาแกน

3

โครงการของเราใช้ "คำนำหน้า" เป็นคำนำหน้าสำหรับข้อมูลสมาชิกและ "the" เป็นคำนำหน้าสำหรับพารามิเตอร์โดยไม่มีคำนำหน้าสำหรับคนในท้องถิ่น มันเป็นเรื่องเล็ก ๆ น้อย ๆ แต่มันก็เป็นลูกบุญธรรมของนักพัฒนาระบบของเราเพราะพวกเขาเห็นว่ามันใช้เป็นแบบแผนโดยห้องสมุดแหล่งข้อมูลเชิงพาณิชย์ที่เราใช้อยู่ในเวลานั้น (เช่น XVT หรือ RogueWave - อาจทั้งคู่) ดังนั้นคุณจะได้รับสิ่งนี้:

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

เหตุผลใหญ่ที่ฉันเห็นสำหรับการกำหนดขอบเขตหน้า (และไม่มีคนอื่น - ฉันเกลียดสัญกรณ์ฮังการี) คือมันป้องกันไม่ให้คุณประสบปัญหาโดยการเขียนโค้ดที่คุณคิดว่าคุณอ้างถึงตัวแปรตัวหนึ่ง แต่จริงๆแล้วคุณอ้างถึงตัวแปรอื่น ด้วยชื่อเดียวกันที่กำหนดไว้ในขอบเขตท้องถิ่น นอกจากนี้ยังช่วยหลีกเลี่ยงปัญหาที่จะเกิดขึ้นกับชื่อตัวแปรเพื่อแสดงแนวคิดเดียวกัน แต่มีขอบเขตต่าง ๆ เช่นตัวอย่างข้างต้น ในกรณีดังกล่าวคุณจะต้องมีคำนำหน้าหรือชื่อที่แตกต่างกันสำหรับพารามิเตอร์ "theName" ต่อไป - ทำไมไม่สร้างกฎที่สอดคล้องกันที่ใช้กับทุกที่

เพียงแค่ใช้สิ่งนี้ -> ยังไม่ดีพอ - เราไม่สนใจลดความคลุมเครือในการลดข้อผิดพลาดในการเขียนโค้ดและการปิดบังชื่อด้วยตัวระบุที่มีขอบเขตเฉพาะที่อาจทำให้เกิดความเจ็บปวดได้ ได้รับคอมไพเลอร์บางตัวอาจมีตัวเลือกในการเพิ่มคำเตือนสำหรับกรณีที่คุณปิดบังชื่อในขอบเขตที่กว้างขึ้น แต่คำเตือนเหล่านั้นอาจกลายเป็นเรื่องน่ารำคาญถ้าคุณทำงานกับห้องสมุดบุคคลที่สามขนาดใหญ่ที่เลือกไว้ ชื่อสำหรับตัวแปรที่ไม่ได้ใช้ซึ่งบางครั้งขัดแย้งกับตัวคุณเอง

สำหรับตัวมัน / ตัวเอง - ฉันพบว่าพิมพ์ได้ง่ายกว่าขีดล่าง (ในฐานะผู้พิมพ์ดีดสัมผัสฉันจะหลีกเลี่ยงการขีดเส้นใต้ทุกครั้งที่เป็นไปได้) และฉันพบว่ามันอ่านง่ายกว่าขีดล่างลึกลับ


นี่เป็นทางออกที่ใช้งานง่ายที่สุดด้วยช่วงการเรียนรู้ที่เร็วที่สุดที่ฉันเคยได้ยิน ฉันต้องการให้ภาษาพูดมีความยืดหยุ่นในการจัดการกับสิ่งเหล่านั้นมากขึ้นเพื่อที่เราจะได้ไม่ต้องคิดถึงวิธีการใหม่ ๆ ในการแก้ปัญหาความคลุมเครือในโค้ด
Guney Ozsan

2

ฉันใช้มันเพราะ IntelliSense ของ VC ++ ไม่สามารถบอกได้ว่าเมื่อใดที่จะแสดงสมาชิกส่วนตัวเมื่อเข้าออกนอกห้องเรียน สิ่งบ่งชี้เพียงอย่างเดียวคือสัญลักษณ์ "ล็อค" เล็ก ๆ บนไอคอนฟิลด์ในรายการ Intellisense มันทำให้การระบุสมาชิกส่วนตัว (ฟิลด์) ง่ายขึ้น นอกจากนี้นิสัยจาก C # จะซื่อสัตย์

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

ฉันคิดว่าถ้าคุณต้องการคำนำหน้าเพื่อแยกความแตกต่างของสมาชิกชั้นเรียนจากพารามิเตอร์ฟังก์ชั่นสมาชิกและตัวแปรท้องถิ่นฟังก์ชั่นนั้นใหญ่เกินไปหรือตัวแปรนั้นมีชื่อไม่ดี ถ้ามันไม่พอดีกับหน้าจอคุณจะเห็นว่าอะไรคือ refactor

เนื่องจากพวกเขามักจะประกาศห่างไกลจากที่พวกเขาใช้ฉันพบว่าการตั้งชื่อแบบแผนสำหรับค่าคงที่ทั่วโลก (และตัวแปรทั่วโลกแม้ว่า IMO ไม่จำเป็นต้องใช้สิ่งเหล่านี้) แต่อย่างอื่นฉันไม่เห็นความต้องการมาก

ที่กล่าวว่าฉันเคยใส่ขีดเส้นใต้ในตอนท้ายของสมาชิกชั้นเรียนส่วนตัวทั้งหมด เนื่องจากข้อมูลทั้งหมดของฉันเป็นแบบส่วนตัวนี่ก็หมายความว่าสมาชิกมีขีดล่าง ฉันมักจะไม่ทำสิ่งนี้ในรหัสฐานใหม่ แต่เนื่องจากในฐานะโปรแกรมเมอร์คุณส่วนใหญ่ทำงานกับรหัสเก่าฉันยังคงทำสิ่งนี้มาก ฉันไม่แน่ใจว่าความอดทนของฉันต่อนิสัยนี้มาจากความจริงที่ว่าฉันเคยทำสิ่งนี้มาตลอดและยังคงทำอยู่เป็นประจำหรือว่ามันสมเหตุสมผลกว่าการทำเครื่องหมายของตัวแปรสมาชิก


2
สิ่งนี้สะท้อนความรู้สึกของฉันเกี่ยวกับปัญหานี้อย่างมาก ควรอ่านรหัสได้โดยไม่ต้องใช้คำนำหน้า บางทีเราอาจไม่เห็นคำนำหน้ามากมายใช้ในภาษาที่ทันสมัยมากขึ้นเนื่องจากชุมชนผู้ใช้ของพวกเขาได้อ่านง่ายกว่าสิ่งที่คุณเห็นใน C ++ แน่นอน C ++ สามารถและควรอ่านได้ เป็นเพียงว่า C ++ ที่อ่านไม่ได้จำนวนมากถูกเขียนขึ้นในช่วงหลายปีที่ผ่านมา
VoidPointer


1

มันจะมีประโยชน์ในการแยกความแตกต่างระหว่างตัวแปรสมาชิกและตัวแปรท้องถิ่นเนื่องจากการจัดการหน่วยความจำ ตัวแปรสมาชิกที่จัดสรรฮีปควรจะถูกทำลายใน destructor ในขณะที่ตัวแปรโลคอลที่จัดสรรโดยฮีพควรถูกทำลายภายในขอบเขตนั้น การใช้หลักการตั้งชื่อกับตัวแปรสมาชิกช่วยให้การจัดการหน่วยความจำถูกต้อง


งั้นเหรอ destructor ไม่มีสิทธิ์เข้าถึงตัวแปรโลคัลที่ประกาศในฟังก์ชันอื่นดังนั้นจึงไม่มีที่ว่างสำหรับความสับสน นอกจากนี้กองจัดสรรตัวแปรท้องถิ่นไม่ควรอยู่ และควรมีตัวแปรสมาชิกที่จัดสรรฮีปไว้ในคลาส RAII เท่านั้น
jalf

"ไม่ควรมีตัวแปรโลคัลที่จัดสรรฮีพไว้" ค่อนข้างแข็งแกร่ง แต่ถ้าหาก / เมื่อคุณใช้มันสิ่งสำคัญที่สุดคือต้องแน่ใจว่าพวกเขาได้รับการจัดสรรคืนอย่างถูกต้องดังนั้นระเบียบการตั้งชื่อที่มีระเบียบวินัยสำหรับสมาชิกเมื่อเทียบกับตัวแปรในท้องถิ่นจะช่วยให้มั่นใจได้อย่างเต็มที่
frankster

1

Code Complete แนะนำให้ m_varname สำหรับตัวแปรสมาชิก

ในขณะที่ฉันไม่เคยคิดว่าสัญกรณ์ m_ มีประโยชน์ฉันจะให้น้ำหนักความเห็นของ McConnell ในการสร้างมาตรฐาน


2
ไม่เว้นแต่เขาจะอธิบายว่าทำไมขีดเส้นใต้ ฉันเป็นแฟนตัวยงของหนังสือ "การพัฒนาอย่างรวดเร็ว" ของเขาซึ่งฉันได้แนะนำไว้ที่นี่หลายครั้ง แต่น้อยกว่า "รหัสเสร็จสมบูรณ์" (ซึ่งฉันจะยอมรับว่าฉันยังไม่ได้อ่านตั้งแต่แรกออกมา)

1

ฉันแทบไม่เคยใช้คำนำหน้าต่อหน้าชื่อตัวแปรของฉัน หากคุณใช้ IDE ที่ดีพอคุณควรจะสามารถสร้างใหม่และค้นหาการอ้างอิงได้อย่างง่ายดาย ฉันใช้ชื่อที่ชัดเจนมากและไม่กลัวที่จะมีชื่อตัวแปรยาว ๆ ฉันไม่เคยมีปัญหากับขอบเขตด้วยปรัชญานี้

ครั้งเดียวที่ฉันใช้คำนำหน้าจะอยู่ในบรรทัดลายเซ็น ฉันจะใส่คำนำหน้าพารามิเตอร์กับเมธอดด้วย _ ดังนั้นฉันจึงสามารถตั้งโปรแกรมป้องกันรอบตัวพวกมันได้


1

คุณไม่ควรใช้คำนำหน้าเช่นนั้น หากคำนำหน้าดังกล่าวให้ประโยชน์ใด ๆ แก่คุณรูปแบบการเขียนโค้ดของคุณต้องแก้ไขโดยทั่วไปและไม่ใช่คำนำหน้าที่ทำให้รหัสของคุณไม่ชัดเจน ชื่อตัวแปรที่ไม่ดีทั่วไป ได้แก่ "other" หรือ "2" คุณไม่ได้แก้ไขด้วยการกำหนดให้เป็น mOther คุณแก้ไขได้โดยให้ผู้พัฒนาคิดเกี่ยวกับสิ่งที่ตัวแปรนั้นทำในบริบทของฟังก์ชันนั้น บางทีเขาอาจหมายถึง remoteSide หรือ newValue หรือ secondTestListener หรือสิ่งที่อยู่ในขอบเขตนั้น

มันเป็นยุคสมัยที่มีประสิทธิภาพซึ่งยังคงแพร่กระจายอยู่ไกลเกินไป หยุดนำหน้าตัวแปรของคุณและให้ชื่อที่เหมาะสมแก่พวกเขาซึ่งความคมชัดสะท้อนถึงระยะเวลาที่ใช้ มากถึง 5 บรรทัดคุณสามารถเรียกว่า "i" โดยไม่มีความสับสน เกินกว่า 50 บรรทัดคุณต้องมีชื่อที่ค่อนข้างยาว


1

ฉันชอบชื่อตัวแปรที่ให้ความหมายเฉพาะกับค่าที่มีอยู่และปล่อยให้วิธีการประกาศ / นำไปใช้นอกชื่อ ฉันต้องการที่จะรู้ว่าค่าหมายถึงระยะเวลา บางทีฉันอาจทำมากกว่าการรีแฟคเตอร์เฉลี่ยโดยเฉลี่ย แต่ฉันพบว่าการฝังสิ่งที่ใช้ในชื่อทำให้การรีฟอร์เรจน่าเบื่อกว่าที่ควรจะเป็น คำนำหน้าระบุว่าสมาชิกวัตถุหรือวิธีการประกาศมีการใช้งานที่เฉพาะเจาะจง

color = Red;

ส่วนใหญ่ฉันไม่สนใจหรอกว่า Red จะเป็น enum, struct หรืออะไรก็ตามและถ้าฟังก์ชั่นมีขนาดใหญ่จนฉันจำไม่ได้ว่ามีการประกาศสีในพื้นที่หรือเป็นสมาชิกมันอาจถึงเวลาที่จะทำลาย ฟังก์ชันเป็นหน่วยโลจิคัลที่เล็กกว่า

หากความซับซ้อนของวงจรของคุณนั้นยอดเยี่ยมมากจนคุณไม่สามารถติดตามสิ่งที่เกิดขึ้นในรหัสโดยไม่มีการระบุเฉพาะการใช้งานที่ฝังอยู่ในชื่อของสิ่งต่าง ๆ ส่วนใหญ่คุณจะต้องลดความซับซ้อนของฟังก์ชัน / วิธีการ

ส่วนใหญ่ฉันใช้ 'นี่' ในตัวสร้างและ initializers เท่านั้น


0

ฉันใช้ m_ สำหรับตัวแปรสมาชิกเพื่อใช้ประโยชน์จาก Intellisense และการทำงานของ IDE ที่เกี่ยวข้อง เมื่อฉันเขียนโค้ดการใช้งานคลาสฉันสามารถพิมพ์ m_ และดู combobox โดยที่สมาชิก m_ ทั้งหมดรวมกลุ่มกัน

แต่ฉันสามารถอยู่ได้โดยปราศจาก m_ โดยไม่มีปัญหาแน่นอน มันเป็นแค่สไตล์การทำงานของฉัน


คุณสามารถพิมพ์this->
Toast

0

อ้างอิงจากการต่อสู้ของนักสู้ทางอากาศ C ++ มาตรฐานการเข้ารหัส (ธันวาคม 2548):

AV กฎ 67

ข้อมูลสาธารณะและการป้องกันควรใช้ใน structs ไม่ใช่คลาส เหตุผล: คลาสสามารถรักษาค่าคงที่ได้โดยควบคุมการเข้าถึงข้อมูล อย่างไรก็ตามคลาสไม่สามารถควบคุมการเข้าถึงสมาชิกได้หากสมาชิกเหล่านั้นไม่ใช่แบบส่วนตัว ดังนั้นข้อมูลทั้งหมดในชั้นเรียนควรเป็นแบบส่วนตัว

ดังนั้นคำนำหน้า "m" จึงกลายเป็นเรื่องไม่สมควรเนื่องจากข้อมูลทั้งหมดควรเป็นแบบส่วนตัว

แต่มันก็เป็นนิสัยที่ดีที่จะใช้คำนำหน้า p หน้าตัวชี้เนื่องจากเป็นตัวแปรที่อันตราย


0

การประชุมหลายครั้งมาจากเวลาที่ไม่มีบรรณาธิการที่มีความซับซ้อน ฉันอยากจะแนะนำให้ใช้ IDE ที่เหมาะสมที่ช่วยให้คุณกำหนดสีของตัวแปรทุกชนิด สีสามารถมองเห็นได้ง่ายกว่าสีนำหน้า

หากคุณต้องการรายละเอียดเพิ่มเติมเกี่ยวกับตัวแปรใด ๆ IDE สมัยใหม่ควรจะสามารถแสดงให้คุณเห็นได้โดยการย้ายคาเร็ตหรือเคอร์เซอร์ไปที่มัน และถ้าคุณใช้ตัวแปรในทางที่ผิด (เช่นตัวชี้ที่มีตัวดำเนินการ.) คุณจะได้รับข้อผิดพลาด

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.