ทำไมคอนสตรัคเตอร์แบบไร้พารามิเตอร์เริ่มหายไปเมื่อคุณสร้างด้วยพารามิเตอร์


161

ใน C #, C ++ และ Java เมื่อคุณสร้างคอนสตรัคเตอร์ที่รับพารามิเตอร์พารามิเตอร์ไร้ค่าเริ่มต้นจะหายไป ฉันยอมรับข้อเท็จจริงนี้มาโดยตลอด แต่ตอนนี้ฉันเริ่มสงสัยแล้วว่าทำไม

อะไรคือสาเหตุของพฤติกรรมนี้? มันเป็นเพียงแค่ "มาตรการความปลอดภัย / คาดเดา" การพูดว่า "ถ้าคุณสร้างคอนสตรัคเตอร์ของคุณเองคุณอาจไม่ต้องการให้สิ่งนี้แฝงตัว" หรือมีเหตุผลทางเทคนิคที่ทำให้คอมไพเลอร์ไม่สามารถเพิ่มได้เมื่อคุณสร้าง Constructor ด้วยตัวเอง?


7
คุณสามารถเพิ่ม C ++ ลงในรายการภาษาที่มีพฤติกรรมนี้
Henk Holterman

18
และใน C ++ ตอนนี้คุณสามารถบอกได้ว่าFoo() = default;จะเอามันกลับคืนมา
MSalters

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

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

7
@HenkHolterman C ++ ไม่ได้เป็นเพียงแค่พฤติกรรมนี้ แต่เป็นผู้ริเริ่มและอนุญาตให้ใช้งานร่วมกับ C ได้ดังที่ Stroustrup ได้กล่าวถึงในการออกแบบและวิวัฒนาการของ C ++และได้สรุปไว้ในคำตอบที่ปรับปรุงแล้วของฉัน
จอนฮันนา

คำตอบ:


219

ไม่มีเหตุผลที่คอมไพเลอร์ไม่สามารถเพิ่มคอนสตรัคเตอร์ได้ถ้าคุณเพิ่มของคุณเอง - คอมไพเลอร์สามารถทำสิ่งที่มันต้องการได้! อย่างไรก็ตามคุณต้องดูว่าอะไรเหมาะสมที่สุด:

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

ดังนั้นในแต่ละกรณีคุณจะเห็นว่าพฤติกรรมของคอมไพเลอร์ปัจจุบันเหมาะสมที่สุดในแง่ของการรักษาเจตนาที่น่าจะเป็นของโค้ด


2
ฉันคิดว่าคำตอบที่เหลือของคุณจะพิสูจน์ประโยคแรกของคุณผิด
Konrad Rudolph

76
@KonradRudolph ประโยคแรกพูดว่าคอมไพเลอร์จะเพิ่มนวกรรมิกในสถานการณ์นี้ - ส่วนที่เหลือของคำตอบที่อธิบายว่าทำไมมันไม่ได้ (สำหรับภาษาที่ระบุไว้ในคำถาม)
JohnL

1
ไม่ดี ถ้าเราออกแบบภาษา OO ตั้งแต่เริ่มต้นความหมายที่ชัดเจนที่สุดของการไม่มีคอนสตรัคเตอร์คือ "คุณละเลยที่จะเพิ่มตัวสร้างที่ทำให้แน่ใจว่าคลาสคงที่" และจะทำให้เกิดข้อผิดพลาดในการคอมไพล์
จอนฮันนา

70

ไม่มีเหตุผลทางเทคนิคที่แน่นอนว่าทำไมภาษาถึงมีต้องได้รับการออกแบบด้วยวิธีนี้

มีสี่ตัวเลือกที่ค่อนข้างเหมือนจริงที่ฉันเห็น:

  1. ไม่มีตัวสร้างเริ่มต้นเลย
  2. สถานการณ์ปัจจุบัน
  3. เสมอให้สร้างเริ่มต้นโดยเริ่มต้น แต่ปล่อยให้มันถูกปราบปรามอย่างชัดเจน
  4. จัดให้มีคอนสตรัคเตอร์เริ่มต้นเสมอโดยไม่อนุญาตให้ถูกระงับ

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

ตัวเลือก 2 ฉันสบายดี

ตัวเลือก 3 ขัดแย้งกับการไหลของทั้ง Java และ C # สำหรับส่วนที่เหลือของภาษา ไม่มีสิ่งใดที่คุณ "ลบ" อย่างชัดเจนเว้นแต่คุณจะนับว่าทำให้สิ่งต่างๆเป็นส่วนตัวมากกว่าที่เป็นอยู่ใน Java

ทางเลือกที่ 4 เป็นที่น่ากลัว - คุณอย่างแน่นอนต้องการที่จะสามารถที่จะบังคับให้การก่อสร้างที่มีค่าบางอย่าง จะnew FileStream()หมายถึงอะไร

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


1
ฉันชอบตัวเลือก 3 เพราะเมื่อฉันกำลังเขียนบางสิ่งฉันต้องมีตัวสร้างทั้งสองประเภทบ่อยกว่าจากนั้นก็แค่ตัวสร้างพร้อมพารามิเตอร์ ดังนั้นฉันอยากจะสร้างคอนสตรัคเตอร์แบบไม่ใช้พารามิเตอร์สักครั้งแล้วเขียน 10 ครั้งต่อวัน แต่นั่นอาจเป็นเพียงฉันฉันกำลังเขียนชั้น seriaziable มาก ...
Petr Mensik

8
@PetrMensik: หากคอนสตรัคเตอร์แบบไม่มีพารามิเตอร์ของคุณไม่ต้องทำอะไรเลยมันเป็นซับไลน์เดียวซึ่งแน่นอนว่าจะไม่ใช้โค้ดมากกว่าคำสั่ง "ลบอย่างชัดเจน"
Jon Skeet

2
@PetrMensik: ขออภัยฉันเข้าใจผิดใช่ นั่นเป็นสิ่งที่ตรงกันข้ามกับประสบการณ์ของฉัน - และฉันขอยืนยันว่าการรวมบางสิ่งโดยอัตโนมัติเป็นตัวเลือกที่อันตรายกว่าเช่นกัน ... หากคุณบังเอิญจบลงด้วยการไม่รวมมันคุณสามารถทำให้ค่าคงที่ของคุณ ฯลฯ
Jon Skeet

2
# 4 เป็นกรณีที่มี C # structs สำหรับดีขึ้นหรือแย่ลง
Jay Bazuzi

4
ฉันชอบตัวเลือกที่ 1 เพราะง่ายต่อการเข้าใจ ไม่มี constructor "เวทมนต์" ที่คุณมองไม่เห็นในโค้ด ด้วยตัวเลือกที่ 1 คอมไพเลอร์ควรปล่อยคำเตือนเมื่อ (หรืออาจไม่อนุญาต) ชั้นที่ไม่คงที่ไม่มีตัวสร้างอินสแตนซ์ วิธีการ: "ไม่พบตัวสร้างอินสแตนซ์สำหรับคลาส <TYPE> คุณหมายถึงการประกาศคลาสแบบคงที่หรือไม่"
Jeppe Stig Nielsen

19

แก้ไข จริงๆแล้วในขณะที่สิ่งที่ฉันพูดในคำตอบแรกของฉันถูกต้องนี่คือเหตุผลที่แท้จริง:

ในการเริ่มต้นมี C C ไม่ใช่เชิงวัตถุ (คุณสามารถใช้วิธีการ OO แต่มันไม่ได้ช่วยคุณหรือบังคับใช้อะไร)

จากนั้นก็มี C With Classes ซึ่งต่อมาถูกเปลี่ยนชื่อเป็น C ++ C ++ นั้นเป็น object-oriented ดังนั้นจึงส่งเสริมให้มีการห่อหุ้มและทำให้มั่นใจว่าวัตถุไม่เปลี่ยนแปลง - ในระหว่างการก่อสร้างและที่จุดเริ่มต้นและจุดสิ้นสุดของวิธีการใด ๆ วัตถุนั้นอยู่ในสถานะที่ถูกต้อง

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

แต่เป้าหมายที่มี C ++ นั้นจะเข้ากันได้กับ C จนถึงจุดที่มากที่สุดเท่าที่จะเป็นไปได้โปรแกรม C ที่ถูกต้องทั้งหมดยังเป็นโปรแกรม C ++ ที่ถูกต้อง (ไม่เป็นเป้าหมายที่ใช้งานได้อีกต่อไปและวิวัฒนาการของ C แยกเป็น C ++) )

หนึ่งผลของสิ่งนี้คือการทำซ้ำในการทำงานระหว่างstructและclassและอดีตทำสิ่ง C วิธี (ทุกสิ่งสาธารณะโดยค่าเริ่มต้น) และหลังทำสิ่งในทางที่ดี OO (ทุกอย่างส่วนตัวโดยค่าเริ่มต้นนักพัฒนาอย่างแข็งขันทำให้สาธารณะสิ่งที่พวกเขาต้องการสาธารณะ)

อีกอย่างคือในการสั่งซื้อ C structซึ่งไม่มีคอนสตรัคเตอร์เนื่องจาก C ไม่มีคอนสตรัคเตอร์ให้ใช้งานได้ใน C ++ ดังนั้นจึงต้องมีความหมายสำหรับวิธีนี้ในการดู C ++ ดังนั้นในขณะที่ไม่มีคอนสตรัคเตอร์จะต่อต้านการฝึกฝน OO ของการรับรองค่าคงที่ C ++ ใช้สิ่งนี้เพื่อหมายความว่ามีคอนสตรัคเตอร์แบบไม่มีพารามิเตอร์เริ่มต้นที่ทำหน้าที่เหมือนมีร่างกายที่ว่างเปล่า

structsตอนนี้C ทั้งหมดใช้ได้แล้ว C ++ structs(ซึ่งหมายความว่าพวกมันเหมือนกับ C ++ classesกับทุกอย่าง - สมาชิกและการสืบทอด - สาธารณะ) ได้รับการปฏิบัติจากภายนอกราวกับว่ามันมีคอนสตรัคเตอร์แบบไม่มีพารามิเตอร์เดียว

อย่างไรก็ตามถ้าคุณใส่ Constructor ไว้ในclassหรือstructคุณก็ทำสิ่งต่าง ๆ ด้วยวิธี C ++ / OO แทนวิธี C และไม่จำเป็นต้องใช้ Constructor เริ่มต้น

ผู้คนยังคงใช้มันแม้ว่าจะไม่สามารถใช้งานร่วมกันได้เป็นอย่างอื่น (มันใช้คุณสมบัติ C ++ อื่น ๆ ที่ไม่ได้อยู่ใน C)

ดังนั้นเมื่อ Java มาพร้อม (ขึ้นอยู่กับ C ++ ในหลาย ๆ ด้าน) และต่อมา C # (ขึ้นอยู่กับ C ++ และ Java ในรูปแบบที่แตกต่างกัน) พวกเขายังคงใช้วิธีนี้เป็นสิ่งที่ coders อาจถูกใช้แล้ว

Stroustrup เขียนเกี่ยวกับเรื่องนี้ของเขาในc ++ เขียนโปรแกรมภาษาและมากขึ้นดังนั้นที่มีความสำคัญมากขึ้นกับ "whys" ของภาษาในการออกแบบและวิวัฒนาการของภาษา C ++

=== คำตอบเดิม ===

สมมติว่าสิ่งนี้ไม่ได้เกิดขึ้น

สมมติว่าฉันไม่ต้องการคอนสตรัคเตอร์แบบไม่มีพารามิเตอร์เพราะฉันไม่สามารถทำให้คลาสของฉันเข้าสู่สถานะที่มีความหมายได้หากไม่มี อันที่จริงนี่คือสิ่งที่สามารถเกิดขึ้นได้structใน C # (แต่ถ้าคุณไม่สามารถใช้ all-zeros-and-nulls อย่างมีความหมายstructใน C # ได้คุณจะใช้การปรับให้เหมาะสมแบบไม่เปิดเผยต่อสาธารณะ ข้อบกพร่องการออกแบบในการใช้งานstruct)

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

ซึ่งทำให้ภาษาซับซ้อนยิ่งขึ้น ดีกว่าที่จะไม่ทำมัน

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


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

เหมือนกันกับคำตอบของฉัน ฉันไม่เห็นอะไรผิดปกติที่นี่ดังนั้น +1 จากฉัน
Botz3000

@ Botz3000 ฉันไม่สนใจคะแนน แต่ถ้าพวกเขามีการวิจารณ์ฉันควรอ่าน ถึงกระนั้นก็ทำให้ฉันคิดว่าบางสิ่งที่จะเพิ่มไปข้างต้น
Jon Hanna

1
และอีกครั้งด้วยการลงคะแนนเสียงโดยไม่มีคำอธิบายใด ๆ ได้โปรดถ้าฉันขาดอะไรบางอย่างที่ชัดเจนจนไม่ต้องการคำอธิบายเพียงแค่คิดว่าฉันโง่แล้วก็อธิบายให้ฉันฟังหน่อย
จอนฮันนา

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

13

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

หากไม่เป็นเช่นนี้คุณจะต้องมีวิธีปิดใช้งานตัวสร้างเริ่มต้นอย่างชัดเจนหากคุณต้องการให้อ็อบเจกต์สามารถสร้างได้ผ่านคอนสตรัคเตอร์ที่มีพารามิเตอร์


คุณมีตัวเลือกนั้นจริงๆ ทำให้ Constructor ที่ไม่มีพารามิเตอร์เป็นส่วนตัว
mw_21

5
นั่นไม่เหมือนกัน วิธีการใด ๆ ของชั้นเรียนรวมถึงวิธีการแบบคงที่สามารถเรียกมันได้ ฉันชอบที่จะไม่มีมันโดยสิ้นเชิง
Anders Abel

3

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

นี่เป็นกรณีสำหรับวัตถุจำนวนมากที่ไม่เหมาะสมที่จะเริ่มต้นด้วยตัวสร้างที่ว่างเปล่า

มิฉะนั้นคุณต้องประกาศ Constructor แบบไม่มีพารามิเตอร์สำหรับแต่ละคลาสที่คุณต้องการ จำกัด

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


3

ฉันคิดว่าคำถามควรเป็นวิธีอื่น: ทำไมคุณไม่จำเป็นต้องประกาศตัวสร้างเริ่มต้นหากคุณไม่ได้กำหนดตัวสร้างอื่น ๆ

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

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


1

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

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

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

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


1

หลักฐาน

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

วิธีในการลบ Constructor เริ่มต้น

มันตามมาว่าจะต้องมีวิธีในการลบนวกรรมิกสาธารณะแบบไม่มีพารามิเตอร์ การลบนี้สามารถทำได้ในวิธีต่อไปนี้:

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

การเลือกทางออกที่ดีที่สุด

ตอนนี้เราถามตัวเอง: ถ้าไม่มีคอนสตรัคเตอร์แบบไม่มีพารามิเตอร์สิ่งที่มันจะต้องถูกแทนที่ด้วย? และภายใต้สถานการณ์ประเภทใดที่เราต้องการลบนวกรรมิกสาธารณะแบบไม่มีพารามิเตอร์เริ่มต้น

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

  1. เราไม่ต้องการให้คลาสนั้นถูกสร้างอินสแตนซ์เลยหรือเราต้องการควบคุมทัศนวิสัยของนวกรรมิก: ประกาศตัวสร้างที่ไม่ใช่แบบสาธารณะ
  2. เราต้องการบังคับพารามิเตอร์ที่จะให้ในการก่อสร้าง: ประกาศตัวสร้างด้วยพารามิเตอร์

ข้อสรุป

เรามีมัน - สองวิธีที่ C #, C ++ และ Java อนุญาตให้ลบคอนสตรัคเตอร์แบบไม่มีพารามิเตอร์เริ่มต้นได้


มีโครงสร้างที่ชัดเจนและง่ายต่อการติดตาม +1 แต่เกี่ยวกับ (3. ) ด้านบน: ฉันไม่คิดว่าคำหลักพิเศษสำหรับการลบคอนสตรัคเตอร์เป็นความคิดที่น่าอึดอัดใจและในความเป็นจริง C ++ 11 ได้นำมาใช้= deleteเพื่อจุดประสงค์นี้
jogojapan

1

ฉันคิดว่าคอมไพเลอร์นี้จัดการ ถ้าคุณเปิด.netแอสเซมบลีในILDASMคุณจะเห็นตัวสร้างเริ่มต้นแม้ว่าจะไม่ได้อยู่ในรหัส หากคุณกำหนดคอนสตรัคเตอร์แบบกำหนดพารามิเตอร์คอนสตรัคเตอร์เริ่มต้นจะไม่เห็นผึ้ง

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


0

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


0

คลาสต้องการคอนสตรัคเตอร์ มันเป็นข้อกำหนดที่จำเป็น

  • หากคุณไม่ได้สร้างขึ้นหนึ่งตัวสร้างแบบไร้พารามิเตอร์จะมอบให้คุณโดยอัตโนมัติ
  • หากคุณไม่ต้องการคอนสตรัคเตอร์แบบไม่มีพารามิเตอร์คุณต้องสร้างด้วยตัวคุณเอง
  • หากคุณต้องการทั้งคอนสตรัคเตอร์แบบไม่มีพารามิเตอร์และพารามิเตอร์แบบคอนสตรัคเตอร์คุณสามารถเพิ่มได้ด้วยตนเอง

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

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