ปัญหาของการนำ C ++ เหมือน const เป็นภาษามีอะไรบ้าง


17

ฉันสนใจในความคิดของ C ++ - constไม่ใช่การประหารแบบconstนั้น

ยกตัวอย่าง C # - มันไม่มี C ++ - เหมือน const และเหตุผลที่เป็นปกติ - ผู้คนและเวลา ที่นี่นอกจากนี้ดูเหมือนว่าทีม C # ดูการดำเนินการ C ++ ของconstการตลาด CLR และมีเพียงพอที่จุดนี้ (ดูว่าทำไมไม่มีวิธีสมาชิก const ใน c # และพารามิเตอร์ const ; ขอบคุณ Svick) ถ้าเราก้าวไปไกลกว่านั้นมีอะไรอีกไหม?

มีอะไรที่ลึกกว่านี้ไหม? ยกตัวอย่างเช่นการสืบทอดหลาย ๆ อย่างซึ่งมักจะยากที่จะเข้าใจ (สำหรับผู้ใช้) และดังนั้นจึงไม่ได้เพิ่มในภาษา (เช่นปัญหาเพชร)

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

ปรับปรุง : ในขณะที่ฉันพูดถึง C # และทำให้มุมมองทางประวัติศาสตร์ที่ฉันสนใจในลักษณะของปัญหาที่อาจเกิดขึ้นconstกับภาษา

นี่ไม่ใช่ความท้าทายของภาษา โปรดละเว้นปัจจัยเช่นแนวโน้มหรือความนิยมในปัจจุบัน - ฉันสนใจเฉพาะในประเด็นทางเทคนิค - ขอขอบคุณ


3
ในฐานะที่เป็นกัน: มรดกหลายอาจไม่ยากที่จะเข้าใจ แต่วิธีการแก้ปัญหาสามารถกลายเป็นที่น่าเกลียดมาก ความละเอียดที่ไร้เดียงสาอย่างไร้เดียงสาอย่างรวดเร็วกลายเป็นเรื่องง่าย (“ ปัญหาเพชร ”) ลำดับการแก้ไขเมธอด C3 (เผยแพร่ '96) แก้ปัญหานี้ แต่แน่นอนว่าไม่เข้าใจง่าย การประกาศมรดกหลายครั้งอาจดูค่อนข้างสมเหตุสมผล - แต่ปัญหาที่แท้จริงคือ Java มีการกำหนดอัลกอริทึม C3 ไว้ล่วงหน้าและ C # จะเน้นตัวเองหลังจาก Java
amon

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

5
ซ้ำของstackoverflow.com/q/4150478/41071
svick

2
แม้โดยไม่ต้องหลายสืบทอดคุณสามารถแล้วเข้ารหัสปัญหาใด ๆ 3 SAT เป็นวิธีที่ความละเอียด (หรืออย่างแม่นยำมากเกินความละเอียด) ใน C # จึงทำให้ NP-สมบูรณ์
Jörg W Mittag

1
@Svick ขอบคุณมาก เนื่องจากฉันไม่มีคำตอบสำหรับคำถามนี้ฉันใช้เสรีภาพในการแก้ไขอย่างหนักเพื่อมุ่งเน้นไปที่ธรรมชาติของปัญหาไม่ใช่เหตุผลทางประวัติศาสตร์เพราะดูเหมือนว่า 99% ของพวกเขาคือ "เวลา + คน + อคติ C ++ + CLR"
greenoldman

คำตอบ:


10

โปรดทราบว่าสิ่งนี้มีคุณสมบัติเหมาะสมสำหรับคุณหรือไม่ แต่ในภาษาที่ใช้งานได้เช่น Standard ML ทุกอย่างจะไม่เปลี่ยนรูปโดยค่าเริ่มต้น การกลายพันธุ์ได้รับการสนับสนุนผ่านrefประเภทการรับรู้ทั่วไป ดังนั้นintตัวแปรจึงไม่เปลี่ยนรูปและref intตัวแปรจึงเป็นคอนเทนเนอร์ที่ไม่แน่นอนสำหรับints โดยพื้นฐานแล้วตัวแปรคือตัวแปรจริงในความหมายทางคณิตศาสตร์ (ค่าที่ไม่รู้จัก แต่คงที่) และrefs คือ "ตัวแปร" ในแง่การเขียนโปรแกรมที่จำเป็น - เซลล์หน่วยความจำที่สามารถเขียนและอ่านได้ (ฉันชอบเรียกพวกเขาว่ามอบหมายได้)

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

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

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

แก้ไข : หลังจากสะท้อนความคิดเห็นของ greenoldmanฉันตระหนักว่าconstไม่เกี่ยวกับการเปลี่ยนแปลงของข้อมูลโดยตรง constเข้ารหัสเป็นประเภทของวิธีการว่ามีผลข้างเคียงกับอินสแตนซ์หรือไม่

เป็นไปได้ที่จะใช้การกลายพันธุ์เพื่อให้เกิดพฤติกรรมที่โปร่งใสในการอ้างอิง สมมติว่าคุณมีฟังก์ชั่นที่เรียกว่าเมื่อต่อเนื่องส่งกลับค่าที่แตกต่าง - stdinตัวอย่างเช่นฟังก์ชั่นที่อ่านตัวอักษรตัวเดียวจาก เราสามารถใช้แคช / บันทึกผลลัพธ์ของฟังก์ชันนี้เพื่อสร้างค่าอ้างอิงที่โปร่งใส สตรีมจะเป็นรายการที่ลิงก์ซึ่งโหนดจะเรียกใช้ฟังก์ชันในครั้งแรกที่คุณพยายามดึงค่าของพวกเขา แต่จากนั้นแคชผลลัพธ์ ดังนั้นหากstdinconstains Hello, world!เป็นครั้งแรกที่คุณพยายามที่จะเรียกคืนค่าของโหนดแรกก็จะอ่านหนึ่งและผลตอบแทนchar Hหลังจากนั้นก็จะยังคงกลับมาโดยไม่ต้องโทรต่อการอ่านH charในทำนองเดียวกันโหนดที่สองจะอ่านcharจากstdinครั้งแรกที่คุณพยายามดึงค่ามาครั้งนี้กลับมาeและแคชผลลัพธ์

สิ่งที่น่าสนใจที่นี่คือคุณได้เปลี่ยนกระบวนการที่บอกสถานะโดยเนื้อแท้เป็นวัตถุที่ดูเหมือนไร้สัญชาติ แต่มันเป็นสิ่งจำเป็นที่จะกลายพันธุ์รัฐภายในของวัตถุ (โดยแคชผล) เพื่อให้บรรลุนี้ - กลายพันธุ์เป็นผลเป็นพิษเป็นภัย มันเป็นไปไม่ได้ที่จะทำให้เราCharStream constแม้ว่ากระแสจะทำตัวเหมือนค่าที่ไม่เปลี่ยนรูป ตอนนี้คิดว่ามีความเป็นStreamอินเตอร์เฟซกับวิธีการและฟังก์ชั่นทั้งหมดของคุณคาดหวังconst const StreamsคุณCharStreamไม่สามารถใช้อินเทอร์เฟซได้!

( แก้ไข 2:เห็นได้ชัดว่ามีคำหลัก C ++ ที่เรียกmutableว่าจะทำให้เราโกงและทำCharStream constอย่างไรก็ตามช่องโหว่นี้ทำลายconstการค้ำประกัน - ตอนนี้คุณไม่แน่ใจจริงๆว่าบางสิ่งจะไม่กลายพันธุ์ด้วยconstวิธีการของฉันฉันคิดว่าไม่ใช่ ไม่ดีเนื่องจากคุณต้องขอช่องโหว่อย่างชัดเจน แต่คุณยังต้องพึ่งพาระบบการให้เกียรติอย่างสมบูรณ์)

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

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

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


1
+1 ขอบคุณ วัตถุที่ไม่เปลี่ยนรูปนั้นเป็นอย่างอื่นที่ไม่ใช่ C ++ const (เป็นมุมมองที่มากกว่า) แต่พูดว่า C ++ จะมีค่าเริ่มต้นและvarตามความต้องการจะปล่อยให้ปัญหาเดียวเท่านั้น - ความลึก?
greenoldman

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

+1 :-) ปัญหาที่น่าสนใจมากในการอัปเดตของคุณ (อยู่กับลูกแกะที่ไม่ใช่ / const และอาจเป็นปัญหาภายนอกที่อ่อนแอกว่า) ฉันต้องแยกย่อยให้ยาวขึ้น อย่างไรก็ตามสำหรับความคิดเห็นของคุณฉันไม่ได้มีอะไรเลวร้ายในใจ - ค่อนข้างตรงกันข้ามฉันกำลังมองหาคุณสมบัติเพื่อเพิ่มความชัดเจนของรหัส (อีกหนึ่ง: ตัวชี้ที่ไม่ใช่โมฆะ) ประเภทเดียวกันนี่ (อย่างน้อยก็เป็นจุดประสงค์ของฉัน) - ฉันกำหนดfunc foo(const String &s)และนี่คือสัญญาณจะไม่ได้มีการเปลี่ยนแปลงในs foo
greenoldman

1
@greenoldman แน่นอนฉันสามารถดูอุทธรณ์และเหตุผล อย่างไรก็ตามฉันไม่คิดว่าจะมีวิธีแก้ปัญหาที่แท้จริงนอกเหนือจากการหลีกเลี่ยงสถานะที่ไม่แน่นอนได้มากที่สุดเท่าที่จะทำได้ (พร้อมกับสิ่งที่น่ารังเกียจอื่น ๆ เช่นnullและการสืบทอด)
Doval

8

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

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


+1 ขอบคุณ ในขณะที่วัตถุไม่เปลี่ยนรูปเป็นอย่างอื่นที่ฉันกำลังมองหา (คุณสามารถทำให้วัตถุไม่เปลี่ยนรูปแบบใน C # หรือ Java) แม้ด้วยวิธีที่ไม่เปลี่ยนรูปแบบที่คุณต้องตัดสินใจว่ามันลึกหรือตื้นใช้ตัวอย่างเช่นภาชนะของตัวชี้ / อ้างอิง (คุณสามารถ เปลี่ยนค่าของวัตถุที่กำลังชี้ไปที่) หลังจากผ่านไปหนึ่งวันดูเหมือนว่าปัญหาที่สำคัญคือสิ่งที่ถูกตั้งค่าเป็นค่าเริ่มต้นและสามารถแก้ไขได้อย่างง่ายดายเมื่อออกแบบภาษาใหม่
greenoldman

1
+1 สำหรับ lolz @ "บางคนชอบคอมไพเลอร์ของพวกเขาไม่ได้ช่วยฉันไม่เข้าใจคนเหล่านั้น แต่มีพวกเขามากมาย"
Thomas Eding

6

ฉันเห็นข้อเสียคือ:

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

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

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

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

แก้ไข: คำตอบสั้น ๆ ภาษาใหม่มีเนินเขาสูงชันเพื่อปีนขึ้นไปสำหรับการนำไปใช้ นักออกแบบจำเป็นต้องคิดอย่างจริงจังเกี่ยวกับคุณลักษณะที่จำเป็นสำหรับการนำไปใช้ ยกตัวอย่างเช่น Google ตัดทอนการต่อสู้ทางศาสนาที่ลึกที่สุดบางส่วนอย่างไร้ความปราณีโดยการเลือกสไตล์การออกแบบ Conan-the-Barbarian และจริง ๆ แล้วฉันคิดว่าภาษาดีกว่าสำหรับสิ่งที่ฉันได้เห็น


2
สัญลักษณ์แสดงหัวข้อย่อยที่สองของคุณไม่ถูกต้อง ใน C ++ มีสาม / สี่วิธีในการประกาศการอ้างอิง / ตัวชี้ wrt constness: int *ชี้ไม่แน่นอนเพื่อให้มีค่าไม่แน่นอนint const *ชี้ไม่แน่นอนกับค่า const, int * constตัวชี้ const เพื่อให้มีค่าไม่แน่นอนint const * constชี้ const กับค่า const
phresnel

ขอขอบคุณ. ฉันถามเกี่ยวกับธรรมชาติไม่ใช่การตลาด ("อุตสาหกรรมย้ายออกไป" ไม่ใช่ลักษณะของ C ++ - เหมือนconst) ดังนั้น "เหตุผล" เช่นนี้ฉันจึงคิดว่าไม่เกี่ยวข้อง (สำหรับคำถามนี้อย่างน้อย) เกี่ยวกับการconstเป็นพิษ - คุณยกตัวอย่างได้ไหม เพราะ AFAIK มันเป็นข้อได้เปรียบที่คุณผ่านบางสิ่งบางอย่างและมันควรจะยังคงอยู่const const
greenoldman

1
มันไม่ใช่constปัญหา แต่เป็นการเปลี่ยนประเภทจริงๆ - ไม่ว่าคุณจะทำอะไรมันจะเป็นปัญหาเสมอ พิจารณาผ่านแล้วตระหนักถึงคุณผ่านดีกว่าRichString String
greenoldman

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

7
"Const พิษ" ไม่ได้จริงๆปัญหา - ปัญหาที่แท้จริงคือการที่ค่าเริ่มต้น c ++ constไม่ใช่ มันง่ายเกินไปที่จะไม่ใช่constสิ่งที่ควรเป็นconstเพราะคุณต้องเลือกใช้แทนการเลิกใช้
Doval

0

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

แล้วเราต้องการconstอะไรกันล่ะ? ฉันไม่คิดอย่างนั้น ฉันคิดว่าคุณสามารถทำได้โดยไม่ต้องconstถ้าคุณมีการออกแบบที่ดี ข้อมูลใดที่คุณต้องการและที่ไหนซึ่งวิธีใดบ้างที่ใช้วิธี data-to-data และ abstractions ที่คุณต้องการสำหรับ I / O, เครือข่าย, มุมมอง ฯลฯ จากนั้นคุณแยกโมดูลและคลาสที่เกิดขึ้นตามธรรมชาติและคุณมีวิธีและ คลาสที่ไม่เปลี่ยนรูปซึ่งไม่ต้องการสถานะ

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

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


1
"ดังนั้น const ดูเหมือนเป็นไปได้เฉพาะในสถานการณ์ที่คลาส (หรือชนิดที่คุณต้องการประกาศ const) มีความสำคัญ ... " โครงสร้างข้อมูลถาวรนั้นไม่เปลี่ยนรูปและไม่สำคัญ คุณจะไม่เห็นพวกเขาใน C ++ เพราะพวกเขาส่วนใหญ่แบ่งปันข้อมูลภายในระหว่างหลาย ๆ อินสแตนซ์และ C ++ ขาดการรวบรวมขยะเพื่อให้ทำงานได้ "ฉันคิดว่าคุณสามารถทำได้โดยไม่ต้อง const ถ้าคุณมีการออกแบบที่ดี" ค่าที่ไม่เปลี่ยนรูปทำให้โค้ดง่ายขึ้นมากในการให้เหตุผล
Doval

+1 ขอบคุณ คุณช่วยอธิบายให้ชัดเจนเกี่ยวกับ คุณหมายถึงการตั้งคลาสเป็น const หรือไม่? ถ้าใช่ฉันไม่ได้ถามเรื่องนี้ - C ++ const ทำงานเหมือนมุมมองคุณสามารถประกาศ const ถัดจากวัตถุไม่ใช่คลาส (หรือบางอย่างเปลี่ยนไปใน C ++ 11) นอกจากนี้ยังมีปัญหากับย่อหน้าถัดไปและคำว่า "ง่าย ๆ " - มีคำถามที่ดีเกี่ยวกับ C ++ - const ใน C # และปริมาณงานที่เกี่ยวข้องนั้นสำคัญยิ่ง - สำหรับทุกประเภทที่คุณตั้งใจจะใส่const(ใน C ++ sense ) คุณต้องกำหนดอินเตอร์เฟสรวมถึงคุณสมบัติทั้งหมด
greenoldman

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