const int* const Method3(const int* const&) const;
ใครช่วยอธิบายการใช้งานของ const แต่ละตัวได้ไหม
const int* const Method3(const int* const&) const;
ใครช่วยอธิบายการใช้งานของ const แต่ละตัวได้ไหม
คำตอบ:
อ่านสิ่งนี้: https://isocpp.org/wiki/faq/const-correctness
ขั้นสุดท้ายconst
หมายความว่าฟังก์ชันMethod3
ไม่แก้ไขสมาชิกที่ไม่เปลี่ยนแปลงของคลาส
const int* const
หมายถึงตัวชี้ค่าคงที่ไปยังค่าคงที่ int: คือตัวชี้ที่ไม่สามารถเปลี่ยนเป็น int ที่ไม่สามารถเปลี่ยนแปลงได้: ความแตกต่างเพียงอย่างเดียวระหว่างสิ่งนี้กับconst int&
มันสามารถเป็นได้null
const int* const&
หมายถึงการอ้างอิงตัวชี้ค่าคงที่เป็นค่าคงที่ int โดยปกติแล้วพอยน์เตอร์จะไม่ถูกส่งผ่านโดยการอ้างอิง const int* &
มีเหตุผลมากขึ้นเพราะมันจะหมายความว่าตัวชี้สามารถเปลี่ยนแปลงได้ในระหว่างการเรียกใช้เมธอดซึ่งอาจเป็นเหตุผลเดียวที่ฉันเห็นว่าส่งตัวชี้โดยการอ้างอิงconst int* const&
คือเจตนาและวัตถุประสงค์ทั้งหมดเหมือนกับconst int* const
ยกเว้นว่ามันอาจมีประสิทธิภาพน้อยกว่า เนื่องจากพอยน์เตอร์เป็นประเภทข้อมูลเก่าธรรมดา (POD) และโดยทั่วไปแล้วสิ่งเหล่านี้ควรถูกส่งผ่านด้วยค่า
มันง่ายกว่าที่จะเข้าใจถ้าคุณเขียนใหม่ให้เทียบเท่ากันทั้งหมด
// v───v───v───v───v───v───v───v───v───v───v───v─┬┐
// ││
// v──#1 v─#2 v──#3 v─#4 #5
int const * const Method3(int const * const&) const;
จากนั้นอ่านจากขวาไปซ้าย
# 5 กล่าวว่าการประกาศฟังก์ชันทั้งหมดทางด้านซ้ายคือconst
ซึ่งหมายความว่าสิ่งนี้จำเป็นต้องเป็นฟังก์ชันสมาชิกแทนที่จะเป็นฟังก์ชันอิสระ
# 4 บอกว่าตัวชี้ทางด้านซ้ายคือconst
(อาจไม่สามารถเปลี่ยนให้ชี้ไปยังที่อยู่อื่นได้)
# 3 บอกว่าint
ทางซ้ายคือconst
(ไม่สามารถเปลี่ยนเป็นค่าอื่นได้)
# 2 บอกว่าตัวชี้ทางซ้ายคือconst
.
# 1 บอกว่าint
ทางซ้ายคือconst
.
เมื่อรวมทั้งหมดเข้าด้วยกันคุณสามารถอ่านค่านี้เป็นconst
ฟังก์ชันสมาชิกที่ตั้งชื่อMethod3
ซึ่งใช้การอ้างอิงconst
ตัวชี้ไปที่int const
(หรือ a const int
ถ้าคุณต้องการ) และส่งกลับconst
ตัวชี้ไปที่int const
( const int
)
(Nb # 2 ไม่จำเป็นเลย)
ประการแรกconst T
เทียบเท่ากับT const
.
const int* const
int const * const
จึงเทียบเท่ากับ
เมื่ออ่านนิพจน์ที่มีconst
โทเค็นและพอยน์เตอร์จำนวนมากให้พยายามอ่านจากขวาไปซ้าย (หลังจากใช้การแปลงด้านบน) ดังนั้นในกรณีนี้ค่าตอบแทนเป็นตัวชี้ const เพื่อ int
const การทำให้ตัวชี้const
ไม่สมเหตุสมผลที่นี่เนื่องจากค่าที่ส่งคืนไม่ใช่ค่า lvalue ที่สามารถแก้ไขได้ ทำ pointee const
แต่รับประกันว่าผู้ที่โทรมาอาจจะไม่ปรับเปลี่ยนint
(หรืออาร์เรย์ของint
s) Method3
ส่งกลับโดย
const int*const&
กลายเป็นint const*const&
ดังนั้นจึงเป็นการอ้างอิงถึงตัวชี้ const เพื่อ int
const การส่งผ่านตัวชี้ const โดยการอ้างอิงตัวผู้ก็ไม่มีความรู้สึกเช่นกันคุณไม่สามารถแก้ไขค่าที่อ้างอิงได้เนื่องจากตัวชี้เป็นconst
และการอ้างอิงและตัวชี้ใช้พื้นที่เก็บข้อมูลเท่ากันดังนั้นจึงไม่มีการประหยัดพื้นที่ใด ๆ
สุดท้ายconst
บ่งชี้ว่าเมธอดไม่ได้แก้ไขthis
วัตถุ this
ชี้ภายในร่างกายวิธีการที่จะมี (ทฤษฎี) T const * const this
ประกาศ ซึ่งหมายความว่าconst T*
วัตถุจะสามารถโทรT::Method3()
ได้
const
s แรกไว้ที่หัวของวลี นี่เป็นเหตุผลว่าทำไมฉันถึงคิดว่าเป็นการปฏิบัติที่ไม่ดีconst
แม้ว่าภาษาจะอนุญาตและเป็นการใช้งานที่พบบ่อยที่สุด
วิธีง่ายๆในการจำกฎconst
คือการคิดวิธีนี้: const
ใช้กับสิ่งที่อยู่ทางซ้ายเว้นแต่จะไม่มีอะไรอยู่ทางซ้าย
ดังนั้นในกรณีของconst int * const
const ตัวแรกจะไม่มีอะไรอยู่ทางซ้ายดังนั้นจึงใช้กับint
และอันที่สองมีบางอย่างทางซ้ายดังนั้นจึงใช้กับตัวชี้
const int const *
กฎนี้ยังบอกคุณในสิ่งที่จะเกิดขึ้นในกรณีที่คุณมี เนื่องจาก const ทั้งสองใช้กับint
นิพจน์นี้ซ้ำซ้อนจึงไม่ถูกต้อง
const /* don't modify the int or array of ints' value(s) */
int* const /* as a retval, ignored. useless declaration */
Method3(const /* don't modify the int or array of ints' value(s) */
int* const /* don't modify the pointer's value, the address to which `pointer` points to. e.g. you cannot say `++pointer` */
&) const; /* this method does not modify the instance/object which implements the method */
ฉันชอบใช้วิธีการ"นาฬิกา" หรือ "เกลียว"โดยเริ่มจากชื่อตัวระบุ (ในกรณีนี้Method3
) คุณอ่านกลับไปกลับมาจากซ้ายไปขวา - กลับไปซ้าย ฯลฯ เพื่อถอดรหัส หลักการตั้งชื่อ ดังนั้นconst int* const Method3(const int* const&) const
เป็นวิธีการเรียนที่ไม่เปลี่ยนแปลงสมาชิกชั้นใด ๆ (บางระดับยกเลิกการตั้งชื่อ) และใช้อ้างอิงอย่างต่อเนื่องที่จะเป็นตัวชี้ว่าจุดที่จะต้องคงที่และผลตอบแทนที่เป็นตัวชี้คงที่คงที่int
int
หวังว่านี่จะช่วยได้
เจสัน
วิธีง่ายๆในการจำ const ใน C ++ คือเมื่อคุณเห็นรหัสในรูปแบบเช่น:
XXX const;
const YYY;
XXX, YYY จะเป็นส่วนประกอบคงที่
XXX const
รูปแบบ:
function ( def var ) const; ------#1
* const; ------#2
const YYY
แบบฟอร์ม:
const int; ------#3
const double;
คนมักใช้ประเภทเหล่านี้ เมื่อคุณเห็น"const&"
ที่ไหนสักแห่งอย่ารู้สึกสับสน const กำลังอธิบายอะไรบางอย่างต่อหน้าตัวมันเอง ดังนั้นคำตอบของปัญหานี้จึงชัดเจนในตัวเองในตอนนี้
const int* const Method3(const int* const&) const;
| | | | |
#3 #2 #3 #2 #1
ฉันเพียงต้องการที่จะพูดถึงว่าเป็นจริงอย่างต่อเนื่องเพื่อการอ้างอิงconst int* const&
const int*
ตัวอย่างเช่น:
int i = 0;
int j = 1;
int* p = &i;
int* q = &j;
const int* const& cpref = p;
cpref = q; //Error: assignment of read-only reference 'cpref'
นอกจากนี้ยังเป็นกรณีสำหรับint* const&
ซึ่งหมายความว่า: "การอ้างอิงคงที่int*
"
แต่คือการอ้างอิงที่ไม่คงที่const int*&
หวังว่านี่จะช่วยได้ const int*
การอ่านจากขวาไปซ้ายทำให้เข้าใจตัวปรับแต่งได้ง่ายขึ้น
วิธีการ const ที่ใช้การอ้างอิงตัวชี้ const ไปยัง const int ที่เรียกว่าMethod3
ซึ่งจะส่งกลับตัวชี้ const เป็น const int
mutable
)const # 1: ตัวชี้ที่ส่งคืนโดย Method3 หมายถึง const int
const # 2: ค่าตัวชี้ที่ส่งกลับโดยฟังก์ชันคือค่า const นี่คือ const ที่ไร้ประโยชน์ (แม้ว่าจะถูกต้องตามหลักไวยากรณ์) เนื่องจากค่าที่ส่งกลับจากฟังก์ชันไม่สามารถเป็นค่า l ได้
const # 3: ประเภทตัวชี้ที่ส่งผ่านโดยการอ้างอิงไปยังฟังก์ชันชี้ไปที่ const int
const # 4: ค่าตัวชี้ที่ส่งผ่านโดยการอ้างอิงถึงฟังก์ชันคือตัวชี้ const การประกาศค่าที่ส่งผ่านไปยังฟังก์ชันเป็น const โดยปกติจะไม่มีจุดหมาย แต่ค่านี้ถูกส่งผ่านโดยการอ้างอิงดังนั้นจึงมีความหมายได้
const # 5: ฟังก์ชัน (น่าจะเป็นฟังก์ชันสมาชิก) คือ const ซึ่งหมายความว่าไม่อนุญาตให้ (a) กำหนดค่าใหม่ให้กับสมาชิกใด ๆ ของวัตถุที่เป็นส่วนหนึ่งหรือ (b) เรียกฟังก์ชันที่ไม่ใช่สมาชิก const บนวัตถุหรือสมาชิกใด ๆ
const
ในตอนท้ายของเมธอดคือตัวกำหนดคุณสมบัติที่ระบุว่าสถานะของอ็อบเจ็กต์จะไม่มีการเปลี่ยนแปลง
const int*const&
หมายถึงการรับโดยการอ้างอิงตัวชี้ const ไปยังตำแหน่ง const ไม่สามารถเปลี่ยนเพื่อชี้ไปยังตำแหน่งอื่นหรือเปลี่ยนค่าที่ชี้ไป
const int*const
คือค่าส่งคืนซึ่งเป็นตัวชี้ค่าคงที่ไปยังตำแหน่งคงที่
ตัวอย่างบางส่วนอาจแสดงให้เห็นถึงแนวคิดนี้ได้ดียิ่ง imho ยิ่งดี
class TestClass
{
private:
int iValue;
int* oValuePtr;
int& oValueRef;
public:
int TestClass::ByValMethod1(int Value)
{
// Value can be modified
Value++;
// iValue can be modified
iValue = Value;
iValue += 1;
// Return value can be modified
return ++iValue;
}
int TestClass::ByValMethod2(const int Value)
{
// Value *cannot* be modified
// Variable is const variable
Value++;
// iValue can be modified
iValue = Value;
iValue += 1;
// Return value can be modified
return ++iValue;
}
const int TestClass::ByValMethod3(int Value)
{
// Value can be modified
Value++;
// iValue can be modified
iValue = Value;
iValue += 1;
// Return value can be modified
return ++iValue;
}
const int TestClass::ByValMethod4(const int Value)
{
// Value *cannot* be modified
// Variable is const variable
Value++;
// iValue can be modified
iValue = Value;
iValue += 1;
// Return value can be modified
return ++iValue;
}
const int TestClass::ByValMethod5(const int Value) const
{
// Value *cannot* be modified
// Variable is const variable
Value++;
// iValue *cannot* be modified
// Access through a const object
iValue = Value;
iValue += 1;
// Return value *cannot* be modified
// Access through a const object
return ++iValue;
}
int& TestClass::ByRefMethod1(int& Value)
{
// Value can be modified
Value++;
// oValueRef can be modified
oValueRef = Value;
oValueRef += 1;
// Return value can be modified
return ++oValueRef;
}
int& TestClass::ByRefMethod2(const int& Value)
{
// Value *cannot* be modified
// Variable is const variable
Value++;
// oValueRef can be modified
oValueRef = Value;
oValueRef += 1;
// Return value can be modified
return ++oValueRef;
}
const int& TestClass::ByRefMethod3(int& Value)
{
// Value can be modified
Value++;
// oValueRef can be modified
oValueRef = Value;
oValueRef += 1;
// Return value can be modified
return ++oValueRef;
}
const int& TestClass::ByRefMethod4(const int& Value)
{
// Value *cannot* be modified
// Variable is const variable
Value++;
// oValueRef can be modified
oValueRef = Value;
oValueRef += 1;
// Return value can be modified
return ++oValueRef;
}
const int& TestClass::ByRefMethod5(const int& Value) const
{
// Value *cannot* be modified
// Variable is const variable
Value++;
// oValueRef can be modified
oValueRef = Value;
oValueRef += 1;
// Return value can be modified
return ++oValueRef;
}
int* TestClass::PointerMethod1(int* Value)
{
// Value can be modified
Value++;
// oValuePtr can be assigned
oValuePtr = Value;
// oValuePtr can be modified
oValuePtr += 1;
// Return value can be modified
return ++oValuePtr;
}
int* TestClass::PointerMethod2(const int* Value)
{
// Value can be modified
Value++;
// oValuePtr cannot be assigned
// const int* to int*
oValuePtr = Value;
// oValuePtr can be modified
oValuePtr += 1;
// Return value can be modified
return ++oValuePtr;
}
const int* TestClass::PointerMethod3(int* Value)
{
// Value can be modified
Value++;
// oValuePtr can be assigned
oValuePtr = Value;
// iValue can be modified
oValuePtr += 1;
// Return value can be modified
return ++oValuePtr;
}
const int* TestClass::PointerMethod4(const int* Value)
{
// Value cannot be modified
Value++;
// oValuePtr *cannot* be assigned
// const int* to int*
oValuePtr = Value;
// oValuePtr can be modified
oValuePtr += 1;
// Return value can be modified
return ++oValuePtr;
}
const int* TestClass::PointerMethod5(const int* Value) const
{
// Value can be modified
++Value;
// oValuePtr *cannot* be assigned
// const int* to int* const
// Access through a const object
oValuePtr = Value;
// oValuePtr *cannot* be modified
// Access through a const object
oValuePtr += 1;
// Return value *cannot* be modified
return ++oValuePtr;
}
};
ฉันหวังว่านี่จะช่วยได้!