เหตุใดจึงต้องใช้ static_cast <int> (x) แทน (int) x


667

ฉันเคยได้ยินว่าstatic_castควรใช้ฟังก์ชั่น C-style หรือ Simple-style casting มันเป็นเรื่องจริงเหรอ? ทำไม?


36
คัดค้านเกียรติของคุณถามและตอบ
แกรมเพอร์โรว์

25
ฉันไม่เห็นด้วยคำถามอื่นนี้เกี่ยวกับการอธิบายความแตกต่างระหว่างการปลดเปลื้องแนะนำใน C ++ คำถามนี้เกี่ยวกับประโยชน์ที่แท้จริงของ static_cast ซึ่งแตกต่างกันเล็กน้อย
Vincent Robert

2
แน่นอนว่าเราสามารถรวมสองคำถามเข้าด้วยกันได้ แต่สิ่งที่เราต้องการรักษาจากหัวข้อนี้คือข้อดีของการใช้ฟังก์ชั่นการคัดเลือกนักแสดงสไตล์ C ซึ่งปัจจุบันถูกกล่าวถึงในคำตอบเดียวในหัวข้ออื่นโดยไม่มีการลงคะแนน .
Tommy Herbert

6
คำถามนี้เกี่ยวกับประเภท "built-in" เช่น int ในขณะที่คำถามนั้นเกี่ยวกับประเภทของคลาส ซึ่งดูเหมือนว่าจะมีความแตกต่างอย่างมีนัยสำคัญพอที่จะทำบุญอธิบายแยก

9
static_cast เป็นจริงผู้ประกอบการไม่ใช่ฟังก์ชั่น
ThomasMcLeod

คำตอบ:


633

เหตุผลหลักคือการที่ปลดเปลื้อง C คลาสสิกทำให้ความแตกต่างระหว่างสิ่งที่เราเรียกว่าไม่มีstatic_cast<>(), reinterpret_cast<>(), และconst_cast<>() dynamic_cast<>()สี่สิ่งนี้แตกต่างอย่างสิ้นเชิง

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

ในทางกลับกันreinterpret_cast<>()(หรือ a const_cast<>()) เป็นอันตรายเสมอ คุณบอกคอมไพเลอร์: "เชื่อฉัน: ฉันรู้ว่านี่มันไม่เหมือนfoo(นี่ดูราวกับว่ามันไม่แน่นอน) แต่มันเป็น"

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

สมมติว่าสิ่งเหล่านี้:

class CDerivedClass : public CMyBase {...};
class CMyOtherStuff {...} ;

CMyBase  *pSomething; // filled somewhere

ตอนนี้ทั้งสองนี้จะถูกรวบรวมในลักษณะเดียวกัน:

CDerivedClass *pMyObject;
pMyObject = static_cast<CDerivedClass*>(pSomething); // Safe; as long as we checked

pMyObject = (CDerivedClass*)(pSomething); // Same as static_cast<>
                                     // Safe; as long as we checked
                                     // but harder to read

อย่างไรก็ตามเราจะเห็นโค้ดที่เหมือนกันเกือบทั้งหมด:

CMyOtherStuff *pOther;
pOther = static_cast<CMyOtherStuff*>(pSomething); // Compiler error: Can't convert

pOther = (CMyOtherStuff*)(pSomething);            // No compiler error.
                                                  // Same as reinterpret_cast<>
                                                  // and it's wrong!!!

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

ปัญหาที่สองคือรูปแบบ C นั้นยากที่จะค้นหา ในการแสดงออกที่ซับซ้อนอาจเป็นเรื่องยากมากที่จะเห็นรูปแบบ C แทบจะเป็นไปไม่ได้ที่จะเขียนเครื่องมืออัตโนมัติที่จำเป็นต้องค้นหาตำแหน่ง C-style (ตัวอย่างเช่นเครื่องมือค้นหา) โดยไม่ต้องคอมไพเลอร์ C ++ เต็มหน้า ในทางกลับกันการค้นหา "static_cast <" หรือ "reinterpret_cast <" นั้นง่าย

pOther = reinterpret_cast<CMyOtherStuff*>(pSomething);
      // No compiler error.
      // but the presence of a reinterpret_cast<> is 
      // like a Siren with Red Flashing Lights in your code.
      // The mere typing of it should cause you to feel VERY uncomfortable.

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


30
คุณไม่ควรใช้static_castสำหรับการหล่อลงลำดับชั้นมรดก dynamic_castแต่ ที่จะส่งกลับทั้งตัวชี้โมฆะหรือตัวชี้ที่ถูกต้อง
David Thornley

41
@ David Thornley: ฉันเห็นด้วยปกติ ฉันคิดว่าฉันบอก caveats เพื่อใช้static_castในสถานการณ์นั้น dynamic_castอาจปลอดภัยกว่า แต่ก็ไม่ใช่ตัวเลือกที่ดีที่สุดเสมอไป บางครั้งคุณก็รู้ว่าตัวชี้ชี้ไปที่ประเภทย่อยที่กำหนดโดยวิธีทึบแสงให้กับคอมไพเลอร์และ a static_castเร็วขึ้น อย่างน้อยในบางสภาพแวดล้อมdynamic_castจำเป็นต้องมีการสนับสนุนคอมไพเลอร์เพิ่มเติมและค่าใช้จ่ายรันไทม์ (เปิดใช้งาน RTTI) และคุณอาจไม่ต้องการเปิดใช้งานเพียงตรวจสอบสองสามอย่างที่คุณสามารถทำได้ด้วยตัวเอง RTTI ของ C ++ เป็นวิธีแก้ปัญหาที่เป็นไปได้เพียงวิธีเดียวเท่านั้น
Euro Micelli

18
การอ้างสิทธิ์ของคุณเกี่ยวกับ C casts เป็นเท็จ ทั้งหมดปลดเปลื้องซีมีการแปลงค่าประมาณเทียบเท่ากับ C static_cast++ เทียบเท่าซีreinterpret_castเป็น*(destination_type *)&คือการอยู่ของวัตถุที่หล่ออยู่ที่ชี้ไปยังประเภทที่แตกต่างกันแล้ว dereferencing ยกเว้นในกรณีของชนิดอักขระหรือชนิดของโครงสร้างที่ C กำหนดพฤติกรรมของโครงสร้างนี้โดยทั่วไปแล้วจะส่งผลให้เกิดพฤติกรรมที่ไม่ได้กำหนดใน C.
R. GitHub STOP ช่วย ICE

11
คำตอบที่ดีของคุณอยู่ที่เนื้อหาของโพสต์ ฉันกำลังหาคำตอบสำหรับชื่อเรื่อง "ทำไมต้องใช้ static_cast <int> (x) แทน (int) x" นั่นคือสำหรับประเภทint(และintเพียงอย่างเดียว) เหตุใดจึงใช้static_cast<int>กับ(int)เป็นประโยชน์อย่างเดียวที่ดูเหมือนจะอยู่กับตัวแปรคลาสและพอยน์เตอร์ ขอให้คุณทำอย่างละเอียดเกี่ยวกับเรื่องนี้
chux - Reinstate Monica

31
@chux สำหรับint dynamic_castใช้ไม่ได้ แต่เหตุผลอื่น ๆ ทั้งหมดยืน ตัวอย่างเช่นสมมติว่าvเป็นพารามิเตอร์ที่ฟังก์ชั่นการประกาศให้เป็นfloatแล้วคือ(int)v static_cast<int>(v)แต่ถ้าคุณเปลี่ยนพารามิเตอร์float*, (int)vเงียบ ๆ กลายเป็นreinterpret_cast<int>(v)ในขณะที่static_cast<int>(v)ผิดกฎหมายและถูกจับได้อย่างถูกต้องโดยคอมไพเลอร์
Euro Micelli

115

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


3
คุณสามารถค้นหาโดยใช้วงเล็บเช่น "(int)" แต่คำตอบที่ดีและเหตุผลที่ถูกต้องในการใช้การหล่อสไตล์ C ++
Mike

4
@ ไมค์ที่จะหาผลบวกปลอม - การประกาศฟังก์ชั่นที่มีintพารามิเตอร์เดียว
นาธานออสมัน

1
สิ่งนี้สามารถให้ผลเชิงลบที่ผิดพลาดได้: หากคุณกำลังค้นหา codebase ที่คุณไม่ใช่ผู้แต่งเพียงคนเดียวคุณจะไม่พบ C-style cast ที่คนอื่นอาจแนะนำด้วยเหตุผลบางประการ
Ruslan

7
การทำเช่นนี้จะช่วยจัดระเบียบโครงการอย่างไร
Bilow

คุณจะไม่ค้นหา static_cast เนื่องจากเป็นไปได้มากว่าถูกต้อง คุณต้องการกรอง static_cast ในขณะที่คุณค้นหา reinterpret_cast, const_cast และอาจจะเป็น dynamic_cast เพราะมันจะบ่งบอกถึงสถานที่ที่สามารถออกแบบใหม่ได้ C-cast ผสมเข้าด้วยกันและไม่ได้ให้เหตุผลในการคัดเลือกนักแสดง
Dragan

78

ในระยะสั้น :

  1. static_cast<>() ช่วยให้คุณมีความสามารถในการตรวจสอบเวลาคอมไพล์ C-Style cast ไม่ได้
  2. static_cast<>()สามารถเห็นได้อย่างง่ายดายทุกที่ในรหัสที่มา C ++; ในทางตรงกันข้ามการโยน C_Style นั้นยากที่จะมองเห็น
  3. ความตั้งใจจะถ่ายทอดได้ดีขึ้นโดยใช้ C + + casts

คำอธิบายเพิ่มเติม :

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

char c = 10;       // 1 byte
int *p = (int*)&c; // 4 bytes

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

*p = 5; // run-time error: stack corruption

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

int *q = static_cast<int*>(&c); // compile-time error

อ่านเพิ่มเติมเกี่ยวกับ:
อะไรคือความแตกต่างระหว่าง static_cast <> การหล่อสไตล์ C
และ
โยนปกติเทียบกับ static_cast dynamic_cast


21
ฉันไม่เห็นด้วยที่static_cast<>()อ่านได้มากกว่า ฉันหมายถึงบางครั้งมันเป็น แต่ส่วนใหญ่ - โดยเฉพาะอย่างยิ่งในประเภทจำนวนเต็มขั้นพื้นฐาน - เป็นเพียง verbose อย่างน่ากลัวและไม่จำเป็น ตัวอย่างเช่น: นี่คือฟังก์ชันที่สลับไบต์ของคำ 32 บิต มันแทบจะเป็นไปไม่ได้เลยที่จะอ่านโดยใช้การstatic_cast<uint##>()ปลดเปลื้อง แต่ค่อนข้างง่ายที่จะเข้าใจการใช้การ(uint##)ปลดเปลื้อง รูปภาพของรหัส: imgur.com/NoHbGve
ทอดด์เลห์แมน

3
@ToddLehman: ขอบคุณ แต่ฉันไม่ได้พูดalwaysอย่างใดอย่างหนึ่ง (แต่ส่วนใหญ่ใช่แล้ว) มีบางกรณีที่การโยนสไตล์ c นั้นอ่านได้ง่ายกว่า นั่นคือเหตุผลหนึ่งในการคัดเลือกนักแสดงสไตล์คยังคงมีอยู่และเตะใน c ++ imho :) โดยวิธีที่เป็นตัวอย่างที่ดีมาก
Rika

8
@ToddLehman รหัสในภาพนั้นใช้สอง casts ถูกล่ามโซ่ ( (uint32_t)(uint8_t)) เพื่อให้บรรลุไบต์ที่นอกเหนือจากต่ำสุดจะถูกรีเซ็ต สำหรับที่มีค่าบิตและ ( 0xFF &) การใช้งานการปลดเปลื้องทำให้เสียความตั้งใจ
Öö Tiib

28

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

บนพื้นผิว static_cast และ C สไตล์การร่ายปรากฏขึ้นในสิ่งเดียวกันตัวอย่างเช่นเมื่อส่งค่าหนึ่งไปยังอีกค่า:

int i;
double d = (double)i;                  //C-style cast
double d2 = static_cast<double>( i );  //C++ cast

ทั้งสองตัวนี้โยนค่าจำนวนเต็มเป็นสองเท่า อย่างไรก็ตามเมื่อทำงานกับสิ่งต่างๆที่มีความซับซ้อนมากขึ้น ตัวอย่างบางส่วน:

class A {};
class B : public A {};

A* a = new B;
B* b = (B*)a;                                  //(1) what is this supposed to do?

char* c = (char*)new int( 5 );                 //(2) that weird?
char* c1 = static_cast<char*>( new int( 5 ) ); //(3) compile time error

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

ดังนั้นสำหรับ "การคัดเลือกค่า" อย่างเข้มงวดคุณสามารถใช้ static_cast ถ้าคุณต้องการการชี้ polymorphic แบบชี้ขาดของเวลาทำงานให้ใช้ dynamic_cast หากคุณต้องการลืมประเภทจริงๆคุณสามารถใช้ reintrepret_cast และเพื่อที่จะโยน const ออกไปนอกหน้าต่างนั่นก็คือ const_cast

พวกเขาทำให้โค้ดชัดเจนยิ่งขึ้นเพื่อให้ดูเหมือนว่าคุณรู้ว่าคุณกำลังทำอะไรอยู่


26

static_castหมายความว่าคุณไม่สามารถตั้งใจconst_castหรือreinterpret_castซึ่งเป็นสิ่งที่ดี


4
ข้อดีเพิ่มเติม (แต่ค่อนข้างน้อย) มากกว่าการคัดเลือกนักแสดงสไตล์ C คือมันโดดเด่นกว่า (การทำบางสิ่งที่อาจเลวร้ายควรดูน่าเกลียด) และยิ่งสามารถพิมพ์ได้มากขึ้น
Michael Burr

4
ความสามารถในการใช้ grep เป็นข้อได้เปรียบเสมอในหนังสือของฉัน
Branan

7
  1. อนุญาตให้ปลดเปลื้องพบได้ง่ายในรหัสของคุณโดยใช้ grep หรือเครื่องมือที่คล้ายกัน
  2. ทำให้ชัดเจนว่าคุณหล่อแบบไหนและมีส่วนช่วยคอมไพเลอร์ในการบังคับใช้ หากคุณต้องการทิ้ง const-ness เท่านั้นคุณสามารถใช้ const_cast ซึ่งจะไม่อนุญาตให้คุณทำการแปลงประเภทอื่น ๆ
  3. แคสต์นั้นน่าเกลียดชังโดยธรรมชาติ - คุณในฐานะโปรแกรมเมอร์กำลังเขียนทับวิธีที่คอมไพเลอร์จะจัดการรหัสของคุณตามปกติ คุณกำลังพูดกับคอมไพเลอร์ "ฉันรู้ดีกว่าคุณ" ในกรณีนี้มันสมเหตุสมผลที่การแสดงนักแสดงควรจะเป็นสิ่งที่เจ็บปวดพอสมควรที่จะทำและพวกเขาควรจะติดอยู่ในโค้ดของคุณเนื่องจากมันเป็นสาเหตุของปัญหา

ดูการแนะนำC ++ ที่มีประสิทธิภาพ


ฉันเห็นด้วยอย่างสมบูรณ์กับสิ่งนี้สำหรับการเรียน แต่การใช้สไตล์นักแสดง C ++ สำหรับประเภท POD นั้นสมเหตุสมผลหรือไม่?
Zachary Kraus

ฉันคิดอย่างนั้น เหตุผลทั้งหมด 3 ข้อนี้ใช้กับ POD และเป็นประโยชน์ที่จะมีเพียงกฎเดียวแทนที่จะแยกเป็นกฎสำหรับชั้นเรียนและ POD
JohnMcG

น่าสนใจฉันอาจต้องแก้ไขวิธีการปลดเปลื้องของฉันในรหัสในอนาคตสำหรับประเภท POD
Zachary Kraus

7

มันเกี่ยวกับความปลอดภัยประเภทที่คุณต้องการกำหนด

เมื่อคุณเขียน(bar) foo(ซึ่งเทียบเท่ากับreinterpret_cast<bar> fooถ้าคุณยังไม่ได้ให้บริการตัวแปลงประเภท) คุณกำลังบอกคอมไพเลอร์ให้เพิกเฉยต่อความปลอดภัยของประเภทและเพียงทำตามที่ได้บอกไว้

เมื่อคุณเขียนstatic_cast<bar> fooคุณจะขอให้คอมไพเลอร์ตรวจสอบอย่างน้อยว่าการแปลงประเภทมีเหตุผลและสำหรับประเภทที่สำคัญให้แทรกรหัสการแปลงบางส่วน


แก้ไข 2014-02-26

ฉันเขียนคำตอบนี้มานานกว่า 5 ปีแล้วและฉันเข้าใจผิด (ดูความคิดเห็น) แต่ก็ยังได้รับ upvotes!


8
(bar) foo ไม่เท่ากับ reinterpret_cast <bar> (foo) กฎสำหรับ "(TYPE) expr" คือการเลือกสไตล์การเขียน C ++ ที่เหมาะสมที่จะใช้ซึ่งอาจรวมถึง reinterpret_cast
Richard Corden

จุดดี. Euro Micelli ให้คำตอบที่ชัดเจนสำหรับคำถามนี้
Pitarou

1
นอกจากนี้ยังstatic_cast<bar>(foo)มีวงเล็บด้วย reinterpret_cast<bar>(foo)สำหรับเดียวกัน
LF

6

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

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

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

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

มีสองสามคนอื่น ๆ แต่เหล่านี้เป็นคนหลักที่คุณจะเจอ


4

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

double d = 3.14159265;
int    i = static_cast<int>(d);

4
ทำไมทุกคนจะเขียนstatic_cast<int>(d)แม้ว่าเมื่อใด(int)dจะกระชับและอ่านมากขึ้น? (ฉันหมายถึงในกรณีที่เป็นประเภทพื้นฐานไม่ใช่ตัวชี้วัตถุ)
ทอดด์เลห์แมน

@ gd1 - ทำไมทุกคนจะวางความมั่นคงเหนือการอ่านได้? (จริง ๆ แล้วครึ่งร้ายแรง)
ทอดด์เลห์แมน

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

2
static_cast เป็นการตัดสินใจที่ชัดเจนและมีสติในการทำการแปลงเฉพาะ ดังนั้นจึงเป็นการเพิ่มความชัดเจนของเจตนา นอกจากนี้ยังมีประโยชน์อย่างมากในฐานะเครื่องหมายสำหรับค้นหาไฟล์ต้นฉบับสำหรับการแปลงในการตรวจสอบโค้ดบั๊กหรือการอัพเกรดแบบฝึกหัด
Persixty

1
@ToddLehman แตกต่าง: ทำไมทุกคนจะเขียน(int)dเมื่อint{d}อ่านมากขึ้น? คอนสตรัคเตอร์หรือฟังก์ชั่นเหมือนถ้าคุณมี()ไวยากรณ์ไม่เร็วนักที่จะตกอยู่ในวงเล็บของเขาวงกตในฝันร้ายในการแสดงออกที่ซับซ้อน ในกรณีนี้มันจะเป็นแทนint i{d} int i = (int)dIMO ที่ดียิ่งกว่า ที่กล่าวว่าเมื่อฉันต้องการชั่วคราวในการแสดงออกฉันใช้static_castและไม่เคยใช้ตัวสร้าง casts ฉันไม่คิด ฉันใช้(C)castsเมื่อเขียนดีบักอย่างรวดเร็วเท่านั้นcout...
underscore_d
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.