เหตุใดฉันจึงจะเรียนรู้ C ++ 11 โดยรู้จัก C และ C ++ [ปิด]


28

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

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

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

ยกตัวอย่าง C หลังจากหลายปีที่ผ่านมามีหลายคนที่ยังคงเรียนรู้และเขียนโค้ดในซีทำไม? เพราะภาษาดี สิ่งที่ดีหมายถึงคือมันปฏิบัติตามกฎหลายข้อเพื่อสร้างภาษาการเขียนโปรแกรมที่ดี ดังนั้นนอกเหนือจากการมีพลัง (ซึ่งง่ายหรือยากภาษาการเขียนโปรแกรมเกือบทั้งหมด), C เป็นปกติและมีข้อยกเว้นเล็กน้อยถ้ามี อย่างไรก็ตาม C ++ 11 ฉันไม่คิดอย่างนั้น ฉันไม่แน่ใจว่าการเปลี่ยนแปลงที่นำเสนอใน C ++ 11 ทำให้ภาษาดีขึ้น

ดังนั้นคำถามคือ: ทำไมฉันจะเรียนรู้ C ++ 11

learning  c++  c  c++11 

3
ฉันเข้าใจว่าไม่ควรพูดจาโผงผาง C ++ 11 ในฟอรัมนี้และฉันเห็นด้วยอย่างยิ่งกับเรื่องนี้: นักพัฒนาทุกคนมีสิทธิ์ที่จะมีรสนิยมส่วนตัวเกี่ยวกับภาษาและเครื่องมือในการเขียนโปรแกรม อย่างไรก็ตามมีปัญหาอีกมากสำหรับฉัน: ฉันเป็นนักพัฒนา C ++ และฉันไม่ชอบ C ++ 11 ฉันจะถูกบังคับให้ใช้ C ++ 11 หรือออกจากตลาด / เปลี่ยนเป็นภาษาอื่นภายใน ไม่กี่ปี?
Giorgio

ฉันคิดเล็กน้อยเกี่ยวกับเรื่องนั้นแน่นอนว่ามีภาษาที่ทันสมัยกว่าเช่นภาษาโปรแกรม D หรือ Go สิ่งเหล่านี้อาจเหมาะสำหรับโดเมนปัญหาของคุณง่ายขึ้นสอดคล้องกันมากขึ้น ฯลฯ อย่างไรก็ตามส่วนแบ่งการตลาด .. ไม่มีผู้เล่นคนสำคัญในอุตสาหกรรมที่รองรับ D และแม้แต่ Go ดูเหมือนว่าจะเป็นหนึ่งใน "การทดลอง" googles .. ดังนั้นแรงจูงใจเบื้องหลัง C + +11 ควรเป็นการปรับปรุงที่มีประโยชน์ซึ่งช่วยให้คุณสามารถเขียนโค้ดที่อ่านง่ายขึ้นปลอดภัยขึ้นและเร็วขึ้นรวมถึงการสนับสนุนอุตสาหกรรมที่กว้างขวาง
นิลส์

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

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

@ anon: วิธีหนึ่งในการกำจัดส่วนที่เส็งเคร็งของภาษาคือการตัดกับอดีตและเริ่มภาษาใหม่เช่น Apple กำลังทำกับ Swift (เพื่อตั้งชื่อเพียงหนึ่งในตัวอย่างมากมาย) การเชื่อมต่อกับรหัสดั้งเดิมสามารถทำได้ผ่านการรวบรวมแยก ปัญหาของ C ++ คือมันขยายออกไปเรื่อย ๆ อาจเป็นเพราะชุมชนของแฟน ๆ ที่เชื่อว่า C ++ นั้นเป็นภาษาที่แท้จริง Bottom line: ฉันพบ C ++ 03 นิด ๆ หน่อย ๆ แต่มันก็ทำงานได้สำเร็จโดยเฉพาะอย่างยิ่งต้องขอบคุณไลบรารี่อย่าง Qt และ boost ในทางกลับกันฉันจะทำให้ C ++ 11 ปิดมือของฉัน
จอร์โจ

คำตอบ:


24

คุณควรเรียนรู้ถ้าคุณคิดว่าคุณจะต้องรู้ในอนาคตเพื่อที่จะได้งาน หากคุณมั่นใจคุณจะยังคงสามารถทำการตลาดในกลุ่มพนักงานในฐานะ C / C ++ [และสิ่งอื่นที่คุณอาจรู้] แล้วอย่าเรียนรู้ ถ้าเจ้านายของคุณบอกให้คุณใช้ C ++ 11 ให้พูดว่า "ไม่ฉันไม่ทำอย่างนั้น" ถ้าเขายิงคุณให้ไปทำงานที่อื่น เรียนรู้ C ++ 11 เมื่อคุณคาดการณ์ว่าเร็ว ๆ นี้คุณจะไม่สามารถหางานที่น่าพอใจพร้อมทักษะที่คุณรู้

ต้องการชี้แจงเหตุผลของฉัน: ฉันไม่ใช่ anti-C ++ 11 เพียงแค่พูดว่าคุณสามารถพูดคุยคำถามของ OP กับ "ทำไมฉันควรเรียนรู้ X" ฉันไม่เคยเรียน ML, scheme, หรือ haskell เพราะฉันมีงานกับ C และ C ++ ฉันแน่ใจว่าภาษาเหล่านั้นมีประโยชน์กับใครบางคน แต่พวกเขาไม่ได้เป็นประโยชน์สำหรับฉันที่จะเรียนรู้ตอนนี้ หากมีคนเสนอเงินที่ดีให้ฉันในโปรแกรม ML ฉันอาจลองเรียนรู้


3
หากคุณเป็นนักพัฒนา "C / C ++" และหากหัวหน้าของคุณบอกให้คุณใช้ C ++ 11 คุณไม่ควรลองเพิ่มไปที่คลังแสงของคุณหรือไม่ ฉันยอมรับว่าคุณไม่ควรใช้เวลาในการเรียนรู้ภาษาเพียงเพื่อเรียนรู้ภาษา แต่เมื่อเจ้านายของคุณพูดว่า "เรียนรู้สิ่งนี้" มันอาจเป็นความคิดที่ดีที่จะไปข้างหน้าและเรียนรู้ นอกจากนี้ยังทำให้คุณสามารถทำการตลาดได้มากขึ้นเมื่อเทียบกับการอธิบายเกี่ยวกับแอปพลิเคชันถัดไปของคุณว่าคุณถูกไล่ออกจากการดื้อรั้น
Panzercrisis

Haskell ... ตลกเพราะการรวม lambdas ช้าใน C ++ : P
rbaleksandar

85

มันง่ายมาก C ++ 11 ทำให้โค้ดง่ายขึ้นสะอาดขึ้นในการเขียนและเร็วขึ้น

nullptrเป็นการปรับปรุง VAST ที่เก่า0กว่า 0มันชนิดที่ปลอดภัยและไม่แปลงเมื่อมันแตกต่างจาก shouldn't- มันเป็นสิ่งที่ดีสิ่งที่จะไม่แปลงไปยังnullptr intมันไม่สมเหตุสมผลเลยที่จะเกิดขึ้นเลย คุณรู้หรือไม่สิ่งที่คณะกรรมการ C ++ พบเมื่อพวกเขาพยายามที่จะพิจารณา#define NULL nullptr? char c = NULL;สิ่งที่ชอบ มันช่างน่ากลัวขนาดไหน? เหตุผลเดียวที่มีข้อยกเว้นที่นี่คือเพราะboolถือว่าเป็นส่วนประกอบสำคัญซึ่งค่อนข้างผิด - แต่มีอยู่ใน C ++ ก่อนหน้านี้และใน C ความจริงที่nullptrไม่ได้แปลงเป็นสิ่งที่ดีมันยอดเยี่ยมและคุณควรจะรักมัน

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

การปรับปรุงห้องสมุดจะเป็นอย่างไร? สิ่งที่ชอบfunction, unique_ptrและshared_ptrมีมากดีกว่าสิ่งที่อยู่ที่นั่นมาก่อนว่ามันเป็นไปไม่ได้ที่จะยืนยันว่าวิธีที่ C ++ 03 ก็ยังดี

#define adding_func(x, y) ((x)+(y))

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

#define add_twice(x) (x + x)

xโอ้รอฉันหวังว่าคุณไม่ได้เพิ่มหรือบางสิ่งบางอย่าง ซึ่งเวอร์ชันฟังก์ชั่นเทมเพลตมีภูมิคุ้มกันโดยสิ้นเชิง ฉันยังหวังว่าคุณจะไม่ได้ชื่นชมnamespacesยกตัวอย่างเช่น

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

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

ยกตัวอย่าง C หลังจากหลายปีที่ผ่านมามีหลายคนที่ยังคงเรียนรู้และเขียนโค้ดในซีทำไม?

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

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

หากคุณใช้ C หรือ C ++ แบบเก่าคุณจะไม่พบข้อยกเว้นมากมาย

ยกตัวอย่างเช่น C-style array ที่น่าสงสาร? จำนวนคนที่ไม่สามารถรับอาร์เรย์และพอยน์เตอร์ตรงๆในหัวของพวกเขาคือลามกอนาจาร ไม่ต้องพูดถึงความจริงที่ว่า C Standard library นั้นไม่ปลอดภัยอย่างไม่น่าเชื่อ

ข้อโต้แย้งหลักของคุณเต็มไปด้วยความเข้าใจผิดอย่างมีเหตุผลและความเข้าใจผิด


7
> ความจริงที่ว่า nullptr ไม่แปลงเป็นเรื่องดีมันยอดเยี่ยมมากและคุณควรจะรักมัน ตกลงความเห็นของคุณ แต่ใจเย็น ๆ สักครู่เกี่ยวกับสิ่งที่คนอื่นควรจะรักโปรด ... ขั้นตอนต่อไปคือทนายความตอลิบาน C ++!
Emilio Garavaglia

5
ฉันคิดว่าส่วนท้ายของคำตอบของคุณนั้นเป็นสาเหตุที่ทำให้ C ++ เป็นที่ต้องการของ C. ซึ่งไม่เป็นปัญหา "ห้องสมุด C ไม่ปลอดภัย" - วิธีนี้ตอบคำถามได้อย่างไร? ฉันหมายถึงแน่นอนหนึ่งควรเรียนรู้คุณสมบัติใหม่ C ++ 11 ข้อเสนอ แต่ C และ C ++ ไม่ได้หมายถึงการทำสิ่งเดียวกัน ถ้า C ++ เป็น bitch ที่จะใช้งานในระดับต่ำดังนั้น C #, Java, Python และ whatnot ก็เพราะพวกเขาไม่ได้ตั้งใจที่จะทำงานในระดับต่ำ เพียงเพราะการคอมไพล์ C ++ กับโค้ดเนทีฟไม่ได้หมายความว่าคุณสามารถใช้ OO และหน้าการเฆี่ยนตีที่เกี่ยวข้องกับมันสำหรับรหัสระดับเคอร์เนลที่สำคัญ
yati sagade

11
@Shahbaz เห็นได้ชัดว่าคุณต้องเรียนรู้เพิ่มเติมเล็กน้อยเกี่ยวกับภาษาการเขียนโปรแกรม (เช่นระบบประเภทการกำหนดขอบเขตคำศัพท์ ฯลฯ ) ความคิดเห็นของคุณทั้งหมดไม่ตรงกัน เริ่มต้นด้วยหนังสือเล่มนี้: amazon.com/Theories-Programming-Languages-John-Reynolds/dp/ …
SK-logic

5
@yati: C ++ มีระบบโมดูลเช่นเดียวกับฟังก์ชั่น C. Member จะถูกใช้งานเป็นฟังก์ชั่น C แบบธรรมดา มีการใช้งานฟังก์ชันเสมือนเช่นเดียวกับฟังก์ชั่นการโหลดจาก DLL ไม่มีหน้าใดที่เกี่ยวกับสิ่งเหล่านี้ และใช่ว่าแน่นอนที่สุดจะนำไปใช้ สำหรับการเริ่มต้นความเชื่อของคุณที่ว่ายูนิกซ์ที่ดีที่สุดนั้นเป็นเรื่องส่วนตัว ส่วนแบ่งตลาด 5% แนะนำเป็นอย่างอื่น และอย่างที่สองแม้ว่าฉันจะชื่นชม Unix ไปจนถึงจุดจบตัวอย่างหนึ่งจะไม่ตั้งเทรนด์ เช่นเดียวกับตัวอย่างอื่น ๆ ที่คุณอ้างถึง ตัวอย่างอะไร พวกมันไร้ความหมาย C ++ นั้นเหมาะสมกับโพรซีเดอร์เหมือนกับ C คือ
DeadMG

8
@yatisagade C ++ เป็นภาษาแบบหลายกระบวนทัศน์ที่ไม่บังคับใช้ฟังก์ชันเสมือนจริงสำหรับทุกสิ่งและโปรแกรมของฉันใน C ++ ก็คล้ายกัน บางส่วนของมันใช้การออกแบบเชิงวัตถุส่วนของมันทำงานได้ ฯลฯ ขึ้นอยู่กับสิ่งที่แก้ปัญหาย่อยที่ดีที่สุดโดยเฉพาะ ฉันขอบคุณ C ++ สำหรับการเพิ่มสไตล์เชิงวัตถุและฉันขอบคุณ C ++ 11 สำหรับการขยายการสนับสนุนอย่างมากสำหรับการเขียนโปรแกรมการทำงาน
David Stone

29

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

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

ในทางกลับกันหากคุณเคยเขียนโค้ดไลบรารี่ / คอร์ที่เลียนแบบฟังก์ชั่น STL / Boost บางส่วนและพบว่าตัวเองถูก จำกัด ด้วยภาษาเพราะคุณได้รับ 95% ในการแก้ปัญหาที่ยอดเยี่ยมและสง่างาม แต่แล้ว คุณหยุดเพราะคุณค้นพบภาษาเพียงแค่ไม่สนับสนุนสิ่งที่คุณต้องการคุณจะตระหนักถึงพลังที่ยอดเยี่ยมของ C ++ 11 นับตั้งแต่ทีมงานของเราอัพเกรดเป็น VS2010 (และเราได้ค้นพบ Boost ในกระบวนการ) ฉันสามารถสร้างรหัสที่ยอดเยี่ยมออกมาซึ่งจะเป็นไปไม่ได้ก่อนที่จะมีสิ่งต่าง ๆ เช่นการอ้างอิงค่า r และการส่งต่อพารามิเตอร์เทมเพลต

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

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


7
@Shahbaz - ฉันคิดว่าคุณยังขาดความตั้งใจในการเพิ่มฟังก์ชั่นนิรนาม และ "การใช้ตัวแปรโดยไม่นำตัวแปรนั้นมาเป็นข้อมูลเข้า" เรียกว่าการปิดและมีให้บริการในภาษาระดับสูงอื่น ๆ อีกมากมาย หากคุณเขียนโค้ดเทมเพลตจำนวนมากที่มีวัตถุ functor ด้วย C ++ 11 คุณจะได้รับฟังก์ชั่นแลมบ์ดาพร้อมแขนเปิด คิดอย่างนี้ ... เมื่อคอมไพเลอร์สร้างรหัสเครื่องไม่มีสิ่งเช่นฟังก์ชั่นเทมเพลตหรือคลาส พวกมันทั้งหมดคือ "อินสแตนซ์" เพื่อสร้างคลาส / ฟังก์ชันที่เป็นรูปธรรมก่อนถึงจุดนั้น แลมบ์ดาเป็นสิ่งเดียวกันเมื่อพูดถึงเรื่องไร้รัฐ ...
DXM

5
... functors แทนที่จะให้ผู้คนเขียนโค้ดจำนวนหนึ่งรหัสสำหรับแต่ละประเภทของ functor และองค์ประกอบการปิดทุกอย่างที่คุณต้องการส่งผ่าน C ++ 11 ช่วยให้คุณระบุไวยากรณ์ทางลัดและมันจะสร้างอินสแตนซ์ของ functor ภายในทั้งชั้นอัตโนมัติ มันเป็นแม่แบบอินสแตนซ์ โปรดทราบว่าคุณสมบัติเหล่านี้ส่วนใหญ่จะไม่ถูกใช้ใน 98% ของรหัสระดับแอปพลิเคชัน แต่เพิ่มเข้ามาเพื่อสร้างไลบรารี่เช่น STL / Boost ที่มีประสิทธิภาพและง่ายต่อการใช้ / บำรุงรักษา / ดีบักมากขึ้น
DXM

10
@Shahbaz: โอเคคุณไม่เข้าใจฟังก์ชั่นแลมบ์ดาหรือการปิด นั่นเป็นเหตุผล ความจริงที่ว่าพวกเขาใช้ในหลายภาษาควรแนะนำว่าพวกเขามีประโยชน์ไม่ว่าคุณจะเข้าใจหรือไม่และคุณควรเข้าใจพวกเขาก่อนที่จะวิจารณ์พวกเขามากเกินไป
David Thornley

8
@Shahbaz: หากคุณคิดว่าการปิดมีความคล้ายคลึงกับตัวแปรทั่วโลกคุณไม่เข้าใจการปิด (คำแนะนำ: ตัวแปรทั่วโลกทำให้เกิดปัญหาเพราะฟังก์ชั่นใด ๆ สามารถแก้ไขได้) หากคุณเข้าใจแนวคิดของ lambdas ไม่ใช่การนำไปใช้คุณจะไม่นำมาประกอบกับความสับสนของคลาสเทียบกับรหัส ทุกอย่างในมาตรฐาน C ++ นั้นมีเหตุผลที่ทำให้คนฉลาดเป็นจำนวนมาก คุณไม่จำเป็นต้องเห็นด้วยกับเหตุผล แต่ไม่ทราบว่าคุณกำลังวิจารณ์จากความไม่รู้
David Thornley

6
@Shahbaz มีอย่าง คล้ายคลึงกันระหว่างการปิดและ Globals ไม่มีคุณสมบูรณ์หายไปจุด อ่านสิ่งนี้: en.wikipedia.org/wiki/Lambda_calculusและระเบิดสมองของคุณ: en.wikipedia.org/wiki/Combinatory_logic
SK-logic

18

มันยากที่จะเขียนฟังก์ชั่นที่คุณต้องเขียนเนื้อหาของฟังก์ชั่นที่สอดคล้องกับรหัสนอกเหนือจากการตั้งชื่อให้?

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

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

มีการพูดคุยที่ดีโดย Herb Sutter เกี่ยวกับ lambdas บางทีเขาสามารถโน้มน้าวใจคุณได้ดีกว่า:

http://channel9.msdn.com/events/PDC/PDC10/FT13

ทำไมคุณไม่เขียนโค้ดที่นั่นแทนที่จะทำให้มันเป็น lambda-function?

เพราะคุณไม่สามารถทำได้เมื่อคุณใช้อัลกอริธึม STL หรือฟังก์ชั่นใด ๆ ที่คุณใช้ซึ่งคุณต้องผ่านฟังก์ชัน

#define add_func (x, y) ((x) + (y))

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

template<class Lhs, class Rhs>
auto adding_func(const Lhs &lhs, const Rhs &rhs)
                -> decltype(lhs+rhs) {return lhs + rhs;}

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

เพื่อสรุป:

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

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


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

เกี่ยวกับไวยากรณ์มองน่าเกลียดใช้ทั้งสองตัวอย่างเช่น: และbool is_alive; bool thisSpecialObjectOfMineIsAlive;ทั้งสองทำแบบเดียวกัน แต่อันที่สองดูน่าเกลียดจริงๆ ทำไม? เพราะฉันคิดว่าการใส่ข้อมูลเพิ่มเติมผิดทำให้ชัดเจนมากขึ้น แต่ก็ทำตรงกันข้าม มันเป็นข้อตกลงเดียวกันที่นี่ Stroustrup มีความหมายที่ดีโดยให้คุณสมบัติกับเรา แต่เขาก็ไม่ได้ทำให้ดูดี สำหรับฉันนี่แสดงให้เห็นถึงการออกแบบที่ไม่ดี
Shahbaz

3
ดูดี! = ดีและไม่ดี! = ไม่ดี
DeadMG

@Shahbaz: ฉันคิดว่า lambdas เป็นแนวคิดที่ยอดเยี่ยม (และมีมาหลายปีในภาษาอย่าง Lisp) ฉันใช้มันเยอะมากใน Haskell ฉันไม่ค่อยแน่ใจว่าพวกเขาจะเหมาะกับภาษาเช่น C ++, Java และอื่น ๆ พวกเขารู้สึกเหมือนฉันเป็นบางครั้งภายหลัง: สิ่งที่เพิ่มเข้ามาในภายหลังเพราะ lambdas ได้รับความนิยม ทำไมพวกเขาถึงไม่แนะนำภาษาเหล่านี้ตั้งแต่เริ่มแรก? หาก Stroustrup และ Goslin ไม่เคยได้ยินเรื่อง Lisp หรือไม่?
Giorgio

8

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

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

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

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

ทางเลือกในการรักษา "ปกติ" ของ C ++ ให้มากขึ้นคือ ... ทำลายบ่อยขึ้นด้วยการเริ่มต้นใหม่ แต่จะไม่มี C ++ อีกต่อไป

มีความพยายามที่จะทำเช่นนั้น (คิดว่า D เช่น: มุมฉากมากขึ้นเช่น C ++ (แม้กระทั่ง 11) เป็นจริง) แต่พวกเขาเป็นที่นิยม? สาเหตุของการมีโมเมนตัมที่ยากคือความไม่ลงรอยกันกับโค้ดที่มีอยู่จำนวนมากที่ยังต้องรัน

สำหรับฉันแล้ว C ++ 11 เป็นความแตกต่างระหว่างความต้องการใหม่และความเข้ากันได้แบบย้อนหลังอย่างชัดเจน นั่นส่งผลให้ "ความยุ่งเหยิง" บางอย่างของสเป็คและการนำไปใช้งาน จนกว่าค่าใช้จ่ายของ "ความยุ่งเหยิง" นั้นจะน้อยกว่าค่าความไม่ลงรอยกัน ... คุณต้องออกจากการประนีประนอมนั้น

หากคุณไม่สามารถทนต่อได้อีกต่อไปควรพิจารณาภาษาอื่นที่อายุน้อยกว่า C ++ ไม่สามารถทำให้ง่ายขึ้นในแง่นั้น ไม่ได้อยู่ในวัยนี้


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

"C ++ ไม่สามารถทำให้เข้าใจได้ง่ายในแง่นั้นไม่ถึงอายุนี้": ทำไมภาษาโปรแกรมอื่น ๆ (เช่น C, Ada, ... ) ไม่ทำตามเส้นทางเดียวกันแล้ว? อาจจะเป็นเพราะพวกเขามีช่องของตัวเองของการใช้งานและพวกเขาจะไม่ได้คาดว่าจะมีเครื่องมือสำหรับทุกการใช้งานที่เป็นไปได้
Giorgio

@ จอร์โจ: ใช่ ... คุณอาจจะอยู่ในความหมาย "ในทางปฏิบัติ" แต่ในทางทฤษฎี ... ฉันจำวันที่ดีที่ปาสกาลเป็น "ภาษาอ้างอิงการสอน" และadaคือ "ภาษาการเขียนโปรแกรมภาษาทุกอย่าง"
Emilio Garavaglia

ฉันยังได้เรียนรู้การเขียนโปรแกรมในภาษาปาสคาล เท่าที่ฉันรู้ Ada ได้ผ่านการแก้ไขหลายครั้ง แต่การออกแบบพื้นฐานของภาษาไม่ได้ล้มล้าง เช่นเดียวกันกับ C และ Pascal หากต้องการพัฒนาภาษาใหม่จริง ๆ ควรมีความกล้าพอที่จะทำให้ชัดเจนและเริ่มต้นสิ่งใหม่ ๆ เช่น D, Java, C # ปัญหาของฉันกับพา ธ ปัจจุบัน C ++ กำลังเกิดขึ้นคือ (โดยไม่จำเป็น) เริ่มซับซ้อนเกินไป หากหลักการ KISS และ YAGNI นำไปใช้กับการออกแบบซอฟต์แวร์ทำไมพวกเขาไม่ควรนำไปใช้กับการออกแบบภาษาโปรแกรมด้วย?
Giorgio

@Giorgio: โอ้ ... พวกเขาใช้ ... ตามที่คุณพูด หากคุณคิดว่า C # หรือ D มีตัวเลือกที่ดีกว่า "ต้ม" C ++ (การตีความความรู้สึกของคุณ) ให้ใช้พวกเขาแทน C ++ เมื่อเวลาผ่านไปบน C ++ จะช้าลง ตอนนี้ฉันเห็น C ++ 11 ให้โอกาสใหม่แก่ "boiled" C ++ 03 และ D โดยยังมีบางสิ่งที่ขาดหายไปในการทำลายอุปสรรคเริ่มต้น เศรษฐศาสตร์และผลประโยชน์ของบรรษัทมีบทบาทในการพัฒนาและสนับสนุนเงินทุน คุณอยู่ในทฤษฎี แต่โลกแห่งความจริงนั้นซับซ้อนกว่า
Emilio Garavaglia

7

แม้ว่าคุณตัดสินใจที่จะเพิกเฉยคุณลักษณะใหม่ของ C ++ 11 คุณจะยังคงได้รับประโยชน์จากคุณลักษณะเหล่านี้เนื่องจากไลบรารีมาตรฐาน C ++ จะใช้งาน ตัวอย่างเช่นใน C ++ 98 ที่มีตัวแปรประเภทหนึ่งvector<string>อาจเป็นไปได้ที่จะเกิดความเสียหายด้านประสิทธิภาพเนื่องจากจำนวนสำเนาที่จำเป็นต้องใช้เมื่อเวกเตอร์เติบโต ด้วยตัวสร้างการย้าย C ++ 11 มันไม่ใช่ปัญหา ในความเป็นจริงฉันหวังว่า C ++ 11 จะนำคุณสมบัติใหม่ ๆ มาให้เราไม่น้อยโดยเฉพาะในไลบรารีมาตรฐาน


6

หลังจากหลายปีที่ผ่านมามีหลายคนที่ยังคงเรียนรู้และเขียนโค้ดในซีทำไม? เพราะภาษาดี

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

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


คุณยกประโยคของฉันไม่สมบูรณ์ อย่างที่ฉันพูดในประโยคหลังgoodหมายถึงมันปฏิบัติตามกฎของการออกแบบภาษาโปรแกรมที่ดี ฉันไม่รู้ว่าคุณเรียนอยู่ที่ใด แต่ฉันรู้ว่ามี 4 หรือ 5 ประเทศและพวกเขาทั้งหมดเริ่มเรียนรู้การเขียนโปรแกรมกับ C. อย่างที่ฉันพูดกับ C ไม่มีข้อยกเว้น (สิ่งที่ตรงกันข้ามกับ Java) ค้นหาสิ่งก่อสร้างที่ไม่มีข้อยกเว้น)
Shahbaz

1
@Shahbaz: ฉันยกมาทั้งประโยค คุณทำการเชื่อมต่อสาเหตุและฉันบอกว่ามันไม่สมบูรณ์แบบที่สุด โชคดีที่ฉันไม่ได้เรียนอะไรอีกแล้ว :) ฉันทำแบบนั้นเพียงพอแล้ว ฉันอาศัยอยู่ในสหรัฐอเมริกาและเมื่อฉันไปโรงเรียน (มากกว่า 15 ปีที่ผ่านมา) C เป็นภาษาเบื้องต้น อย่างไรก็ตามวันนี้โรงเรียนส่วนใหญ่ในสหรัฐอเมริกาเริ่มต้นด้วย Java และไม่มีโปรแกรมเมอร์หนุ่มสาวจำนวนมากที่รู้จัก C.
Dima

5
@Shahbaz: ฉันไม่เห็นปัญหากับกฎภาษาที่มีข้อยกเว้น ใช่ C เป็นภาษาที่ง่ายกว่า C ++ ในทางกลับกัน C ++ ทำให้การเขียนโค้ดง่ายขึ้น ในการเขียนโค้ดที่ง่ายขึ้นคุณต้องมีคุณสมบัติภาษามากขึ้น ทำให้ภาษาซับซ้อนขึ้น I, สำหรับหนึ่ง, เหมือนสิ่งต่าง ๆ เช่นคลาส, การอ้างอิง, RAII, แม่แบบ, ตัวสร้าง, destructors, ข้อยกเว้นและเนมสเปซ แต่คุณบอกว่าคำถามของคุณไม่เกี่ยวกับ C vs C ++ ดังนั้นฉันจึงไม่ได้เขียนคำตอบนั้น
Dima

5
  • ชุดประกอบถูกสร้างขึ้นเพราะคนไม่ชอบเขียนรหัสเครื่อง
  • C ถูกสร้างขึ้นเพราะผู้คนไม่ชอบเขียนชุดประกอบ
  • C ++ ถูกสร้างขึ้นเพราะคนไม่ชอบเขียน C
  • สร้าง C ++ 11 เพราะคนไม่ชอบเขียน C ++

คุณกำลังจะมาถึงจุดหนึ่งในอาชีพ C ++ ของคุณที่คุณพูดกับตัวเองว่า"ฉันแน่ใจว่า functors นั้นง่ายกว่า"หรือ"ทำไม NULL ถึง int" แล้วคุณจะเข้าใจ C ++ 11


ภาษาทั้งหมดถูกสร้างขึ้นเพราะมีคนไม่ชอบภาษาที่มีอยู่ นั่นไม่ได้ทำให้พวกเขาดีเลย
Shahbaz

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

2
"C ++ 11 ถูกสร้างขึ้นเพราะคนไม่ชอบเขียน C ++": หากพวกเขาไม่ชอบเขียน C ++ เหตุใด C ++ จึงเป็นชุดย่อยของ C ++ 11
Giorgio

1
ควรเป็น: C # และ Java ถูกสร้างขึ้นเพราะคนไม่ชอบเขียน C ++
Calmarius

4

การเรียนรู้มีประโยชน์เสมอ ความรู้คือพลัง.

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

ตัวอย่างหนึ่งคือคำถามของคุณเอง คุณจะไม่สามารถถามได้โดยไม่ต้องเรียนรู้อย่างน้อยสักนิด

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


4

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

C ++ 11 รองรับการแยกความคิดของ 'การย้าย' และ 'การคัดลอก' ใน C ++ ปกติเรามีตัวดำเนินการ = ซึ่งโดยทั่วไปทำทั้งสองอย่างนี้ แต่จริงๆแล้วเรากำลังแสดงความคิดแยกกันสองอย่างกับผู้ดำเนินการหนึ่งรายซึ่งเป็นอันตราย

ตัวอย่างที่ชัดเจนที่สุดของที่ซึ่งสิ่งนี้มีประโยชน์คือ unique_ptr ใหม่ มันมีคุณสมบัติที่ดีที่สุดของ auto_ptr และ scoped_ptr อันเก่า สมมติว่าเราต้องการตัวชี้ที่รับประกันว่าจะเป็นตัวชี้เดียวที่ชี้ไปยังวัตถุ เราจะจัดการกับ a = b อย่างไร ก่อนหน้านี้เราติดอยู่คุณอาจไม่อนุญาตอย่างสมบูรณ์ (เหมือน scoped_ptr) หรือเราสามารถทำสิ่งที่ auto_ptr ทำเมื่อ a = b ขโมยความเป็นเจ้าของจาก b พฤติกรรมของ auto_ptr นี้ทำให้เกิดความสับสนมากเพราะ a = b เปลี่ยนไปตามความเป็นจริง unique_ptr จัดการสิ่งนี้: a = b ไม่ได้รับอนุญาต แต่คุณมี = std :: move (b) เพื่อขโมยความเป็นเจ้าของ สิ่งนี้มีประโยชน์อย่างไร? โดยที่มีการสลับรุ่น (โอเวอร์โหลด) แยกต่างหากซึ่งใช้ซีแมนทิกส์การย้ายมากกว่าการคัดลอกซีแมนทิกส์ ซึ่งหมายความว่าสามารถสลับ Unique_ptr ได้โดยไม่มีปัญหา ซึ่งหมายความว่า unique_ptr ซึ่งแตกต่างจาก auto_ptr ปลอดภัยที่จะใช้ในคอนเทนเนอร์แล้วพูดเรียงลำดับ unique_ptr นั้นเป็นสิ่งสำคัญและเป็นจุดสิ้นสุดของการจัดการหน่วยความจำที่ปลอดภัยเมื่อคุณไม่ต้องการพอยน์เตอร์หลายตัวบนวัตถุเดียวกัน

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

ซีแมนทิกส์ย้ายทำให้การเขียนโค้ดง่ายขึ้นซึ่งจะไม่รั่วไหลและปลอดภัยต่อเธรด


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