ความสามารถในการอ่านเป็นเหตุผลที่ถูกต้องหรือไม่ที่จะไม่ใช้พารามิเตอร์ const in (การอ้างอิง)


24

เมื่อเขียนฟังก์ชั่นบางอย่างฉันพบคำสำคัญ const ในพารามิเตอร์ดังนี้:

void MyClass::myFunction(const MyObject& obj,const string& s1,const string& s2,const string& s3){
}

มักทำให้เกิดการแบ่งบรรทัดออกเป็น 2 บรรทัดใน IDE หรือ vim ดังนั้นฉันต้องการลบคำหลัก const ทั้งหมดในพารามิเตอร์:

void MyClass::myFunction(MyObject& obj,string& s1,string& s2,string& s3){
} 

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


110
"เฮ้ฉันต้องการเปลี่ยนโปรแกรมของฉัน" เพื่อให้สามารถอ่านได้มากขึ้นเป็นเหตุผลที่ไม่ดี
Pieter B

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

43
วิธีที่ดีกว่าในการปรับปรุงความสามารถในการอ่านคือการลดจำนวนอาร์กิวเมนต์
5gon12eder

15
'const' ช่วยเพิ่มความสามารถในการอ่าน ข้อความนี้ชัดเจนว่า obj อาจไม่เปลี่ยนแปลง!
ชาร์ลส์

14
สิ่งที่จะช่วยให้สามารถอ่านได้คือการเพิ่มช่องว่างหลังจากแต่ละเครื่องหมายจุลภาค
sam hocevar

คำตอบ:


182

ความสามารถในการอ่านเป็นเหตุผลที่ถูกต้องในการเรียนรู้ที่จะใช้ช่องว่าง:

void MyClass::myFunction(
        const MyObject& obj,
        const string& s1,
        const string& s2,
        const string& s3
) {
    return;
}

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

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


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

6
@CandiedOrange ฉันประหลาดใจที่คุณไม่ได้ใช้ "แบบฟอร์ม 6" ในคำตอบนี้ ... มันน่าเกลียดน้อยลงอย่างเห็นได้ชัด !
svidgen

6
แบบฟอร์ม 6 สำหรับการชนะ หนึ่ง Tabspace สำหรับการเยื้องระดับหนึ่ง ง่ายและมีประสิทธิภาพ แก้ไขปัญหาแล้ว :)
การแข่งขัน Lightness กับ Monica

2
ตกลงแบบฟอร์ม 6 มันเป็น นี่คือตัวแปรที่ JeffGrigg พูดถึงใน c2
candied_orange

4
@ random832 ฉันคิดว่าเราอยู่ในเขตโรงเก็บจักรยานอย่างมั่นคงแล้ว ต่อไปนี้เป็นวิธีที่เหมาะสมในการแก้ไขปัญหาดังกล่าว: ค้นหาฐานรหัสของคุณเพื่อดูตัวอย่างแนวทางร้านค้าของคุณสอบถามนักพัฒนาในร้านค้าของคุณ แก้ไขข้อพิพาทที่อาจไปทางใดทางหนึ่งกับหนึ่งในสี่ เมื่อไตรมาสที่พูดมีความสอดคล้อง!
candied_orange

52

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

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

void foo_const(std::string const& );
void foo_nc(std::string& );

std::string some_getter();

foo_const(some_getter());      // OK
foo_const("Hello there"); // OK

foo_nc(some_getter()); // error
foo_nc("Nope");   // error

std::string x = some_getter(); // have to do this
foo_nc(x);                     // ok
std::string msg = "Really??";  // and this
foo_nc(msg);                   // ok

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


6
ย่อหน้าที่สองของคุณทำให้ฉันปวดหัวพยายามคิดดูว่าconstมีการอ้างอิงconstหรืออื่น ๆconstและสิ่งconstที่สำคัญที่สุดแน่นอนconst
Mindwin

3
@Mindwin ฉันคิดว่าประชดคือย่อหน้าที่สองของฉันชัดเจนและไม่คลุมเครือและฉันไม่รู้ว่าคุณกำลังพูดถึงอะไร
Barry

2
@Barry แน่นอนว่าไม่ต้องสงสัยเลย แต่ฉันอ่านสองสามย่อหน้าของย่อหน้านั้นเพื่อลองคิดดูว่ามันหมายถึงอะไร ฉันคิดว่าปัญหาบางอย่างก็คือมันสามารถแยกวิเคราะห์ "สมุนไพรซัทเทอร์หมายถึง const (ในการอ้างอิงถึง const) เป็น const ที่สำคัญที่สุด ... " หรือ "Herb Sutter หมายถึง const ใน (อ้างอิงถึง const) มากที่สุด const สำคัญ ... "ฉันเชื่อว่าอันหลังเป็นเพียงการจัดกลุ่มคำที่ถูกต้อง แต่ใช้เวลาสักครู่ในการประมวลผล อาจมีวิธีใช้เครื่องหมายคำพูดเพื่อลบความคลุมเครือหรือไม่
Cort Ammon - Reinstate Monica

1
ฉันคิดว่าสารประกอบที่มียัติภังค์บางส่วนจะกำจัดสิ่งนี้
shawnt00

2
หรือใช้เฉพาะconst&แทนที่จะอ้างอิงconstเป็นคำนาม (-phrase) ที่นั่น
Caleth

21

คำตอบง่ายๆคือ "ไม่"

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

// parameter "foo" is not modified
void fna(Foo& foo);

void fnb(const Foo& foo);

นอกเหนือจากความจริงที่ว่ารุ่นหลังมีความกระชับมากกว่านี้มันยังให้สัญญาที่แข็งแกร่งกว่าและให้คอมไพเลอร์ช่วยคุณรักษาความตั้งใจของคุณ อดีตไม่มีอะไรที่จะป้องกันไม่ให้fna(Foo&)ฟังก์ชั่นจากการปรับเปลี่ยนพารามิเตอร์ที่คุณผ่านมัน

เช่นเดียวกับใน @CandiedOrange คำตอบคุณสามารถใช้ช่องว่างเพื่อวางโค้ดและเพิ่มความสามารถในการอ่าน


14

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

typedef string str;
typedef MyObject MObj;
void MyClass::myFunction(const MObj& o,const str& s1,const str& s2,const str& s3)

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

constเป็นฟังก์ชั่นของรหัสตัวเอง คุณจะไม่ทำให้ฟังก์ชั่นไม่ใช่สมาชิกเพื่อลบMyClass::ส่วนของการประกาศดังนั้นอย่าลบconst


4
ฉันยอมรับว่าข้อมูลโค้ดที่คุณให้นั้นสามารถอ่านได้น้อย มันบังคับให้ผู้อ่านที่จะไปหาสิ่งที่MObjและstrมีและแน่นอนยกคิ้ว มันแปลกโดยเฉพาะอย่างยิ่งชนิดที่มีชื่อคุณมีอยู่แล้วการควบคุมผ่าน: เช่นทำไมคุณไม่เพียงแค่ชื่อMyObjectเป็นMObjจะเริ่มต้นด้วย?
Jason C

3

ความสามารถในการอ่านเป็นเหตุผลที่ถูกต้องหรือไม่ที่จะไม่ใช้ const ในพารามิเตอร์?

ไม่การละเว้นconstสามารถเปลี่ยนแปลงฟังก์ชันการทำงานสูญเสียการป้องกันconstและอาจสร้างรหัสที่มีประสิทธิภาพน้อยลง

มันสามารถบำรุงรักษาเพื่อให้วัตถุพารามิเตอร์ไม่เปลี่ยนแปลงด้วยตนเอง?

แทนที่จะใช้เวลาในการจัดทำโค้ดด้วยตนเอง

void MyClass::myFunction(const MyObject& obj,const string& s1,const string& s2,const string& s3){
  //
}

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

void MyClass::myFunction(const MyObject& obj, const string& s1, const string& s2, 
    const string& s3) {
  // 
}

-1

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

หากฉันเห็นข้อโต้แย้งจำนวนมากในวิธีใดวิธีหนึ่งมันบังคับให้ฉันพิจารณาการสร้าง jaron แบบโครงการ (Matrix, Employee, Rectangle, Account) ที่จะสั้นกว่ามากเข้าใจง่ายกว่า


ตกลง ฉันลังเลที่จะชี้ให้เห็น ดังนั้น "กรณีที่รุนแรง"
blackpen

@cmaster ที่กล่าวว่าบางครั้งในบริบทบางอย่างกับโปรแกรมเมอร์บางคนก็สามารถอ่านได้ ตัวอย่างเช่นในกรณีที่เฉพาะเจาะจงของโปรแกรมที่มีความลึกในการเรียกใช้ Windows API โดยมีผู้อ่านที่คุ้นเคยกับสภาพแวดล้อมนั้นสิ่งต่าง ๆ เช่นtypedef Point * LPPOINTและtypedef const Point * LPCPOINTในขณะที่น่าสะพรึงกลัวสุด ๆ ยังคงมีความหมายโดยนัย ในบริบท แต่ไม่เคยอยู่ในกรณีทั่วไป มันเป็นข้อยกเว้นแปลก ๆ ที่ฉันนึกได้
Jason C

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