อ่าน 5 นาที
ซี++/ซีแอลไอ
มาตรฐานเอคม่า/เปลี่ยนทางจากชื่ออื่น
C++/CLIเป็นรูปแบบหนึ่งของภาษาการเขียนโปรแกรมC++ ซึ่งได้รับการดัดแปลงสำหรับโครงสร้างพื้นฐานภาษาทั่วไป (Common Language Infrastructure ) เป็นส่วนหนึ่งของVisual Studio 2005...
ซี++/ซีแอลไอ
| ซี++/ซีแอลไอ | |
|---|---|
| กระบวนทัศน์ | มีโครงสร้าง , เชิงคำสั่ง , เชิงวัตถุ |
| ตระกูล | ซี |
| ออกแบบโดย | ไมโครซอฟต์ |
| นักพัฒนา | ไมโครซอฟต์ |
| ปรากฏครั้งแรก | 2548 |
| แพลตฟอร์ม | โครงสร้างพื้นฐานภาษาทั่วไป |
| เว็บไซต์ | docs.microsoft.com/en-us/cpp/dotnet/dotnet-programming-with-cpp-cli-visual-cpp |
| ได้รับอิทธิพลจาก | |
| C++ , ส่วนขยายแบบจัดการสำหรับ C++ , C# | |
C++/CLIเป็นรูปแบบหนึ่งของภาษาการเขียนโปรแกรมC++ ซึ่งได้รับการดัดแปลงสำหรับโครงสร้างพื้นฐานภาษาทั่วไป (Common Language Infrastructure ) เป็นส่วนหนึ่งของVisual Studio 2005 และเวอร์ชันต่อมา และช่วยให้สามารถทำงานร่วมกับ ภาษา .NET อื่นๆ เช่นC#ได้ Microsoft สร้าง C++/CLI ขึ้นมาเพื่อแทนที่Managed Extensions สำหรับ C++ในเดือนธันวาคม พ.ศ. 2548 Ecma Internationalได้เผยแพร่ข้อกำหนด C++/CLI เป็นมาตรฐานECMA-372 [ 1 ]
เวอร์ชันล่าสุดของ C++ ที่รองรับใน C++/CLI คือC++ 20 [ 2 ]
การเปลี่ยนแปลงไวยากรณ์
ควรพิจารณา C++/CLI ว่าเป็นภาษาเฉพาะของตัวเอง (เช่น มีชุดคีย์เวิร์ดใหม่) แทนที่จะเป็นManaged C++ (MC++) ซึ่งเป็นส่วนขยายของ C++ (โดยคีย์เวิร์ดที่ไม่เป็นมาตรฐานจะถูกเขียนในรูปแบบ `<script>` __gcหรือ ` __value<script>`) ด้วยเหตุนี้ จึงมีการเปลี่ยนแปลงทางไวยากรณ์ที่สำคัญหลายประการ โดยเฉพาะอย่างยิ่งเกี่ยวกับการกำจัดตัวระบุที่ไม่ชัดเจนและการเพิ่มคุณสมบัติเฉพาะของ .NET
ไวยากรณ์ที่ขัดแย้งกันหลายอย่าง เช่น ตัวดำเนินการหลายเวอร์ชันใน MC++ ได้ถูกแยกออกแล้ว: ใน C++/CLI นั้น ประเภทอ้างอิงของ .NET จะถูกสร้างขึ้นด้วยคีย์เวิร์ด new (เช่นมีการเก็บกวาดหน่วยความจำอัตโนมัติ ) นอกจากนี้ C++/CLI ยังได้นำแนวคิดของ generics จาก .NET มาใช้ (คล้ายกับ templates มาตรฐานของ C++ สำหรับการใช้งานทั่วไป แต่แตกต่างกันอย่างมากในการใช้งาน) new()gcnewnew()
C++/CLI ใช้array<T>`array.array.conf` เพื่ออ้างถึงอาร์เรย์ดั้งเดิมของ C# T[]ในขณะที่ใช้ `array.array.conf` System::Array<T>เพื่ออ้างถึงคลาส wrapper System.Array<T>ใน C#
ด้ามจับ
ใน MC++ มีพอยเตอร์ อยู่สองประเภทที่แตกต่างกัน คือ__nogcพอยเตอร์แบบปกติของ C++ และ__gcพอยเตอร์ที่ทำงานกับประเภทอ้างอิงของ .NET อย่างไรก็ตาม ใน C++/CLI พอยเตอร์ประเภทเดียวที่มีอยู่คือพอยเตอร์แบบปกติของ C++ ในขณะที่ประเภทอ้างอิงของ .NET เข้าถึงได้ผ่าน "แฮนเดิล" ด้วยไวยากรณ์ใหม่ClassName^(แทนที่จะเป็นClassName*) โครงสร้างใหม่นี้มีประโยชน์อย่างยิ่งเมื่อมีการผสมผสานโค้ด C++ แบบจัดการและแบบมาตรฐานเข้าด้วยกัน มันช่วยให้เข้าใจได้ชัดเจนว่าวัตถุใดอยู่ภายใต้การเก็บขยะอัตโนมัติของ .NET และวัตถุใดที่โปรแกรมเมอร์ต้องจำไว้ว่าต้องทำลายอย่างชัดเจน
การติดตามข้อมูลอ้างอิง
ใน C++/CLI การอ้างอิงแบบติดตาม (tracking reference)คือตัวจัดการของตัวแปรที่ส่งผ่านโดยการอ้างอิง (passed-by-reference variable) แนวคิดคล้ายกับการใช้การ อ้างอิงไปยังตัวชี้ *&(reference to the pointer) ใน C++ มาตรฐาน และ (ในการประกาศฟังก์ชัน) สอดคล้องกับrefคำหลักที่ใช้กับชนิดข้อมูลใน C# หรือByRefในVisual Basic .NET C++/CLI ใช้^%ไวยากรณ์เพื่อระบุการอ้างอิงแบบติดตามไปยังตัวจัดการ
โค้ดต่อไปนี้แสดงตัวอย่างการใช้งานตัวอ้างอิงแบบติดตาม (tracking references) การแทนที่ตัวอ้างอิงแบบติดตามด้วยตัวแปรแฮนด์เดิลทั่วไป จะทำให้ได้อาร์เรย์สตริงที่มีแฮนด์เดิลสตริงที่ยังไม่ได้กำหนดค่า 10 ตัว เนื่องจากจะมีเพียงสำเนาของแฮนด์เดิลสตริงในอาร์เรย์เท่านั้นที่จะถูกกำหนดค่า เนื่องจากมีการส่งผ่านค่า (by value) แทนที่จะเป็นการส่งผ่านอ้างอิง (by reference)
การใช้เนมสเปซSystem ;int main () { array < String ^>^ arr = gcnew array < String ^> ( 10 ); int i = 0 ;สำหรับแต่ละ( String ^% s ในarr ) { s = i ++ . ToString (); }ส่งคืนค่า0 ; }ตัวดำเนินการขั้นสุดท้ายและตัวแปรอัตโนมัติ
การเปลี่ยนแปลงอีกอย่างใน C++/CLI คือการนำ ไวยากรณ์ finalizer มาใช้ สำหรับคลาสXfinalizer ของมันคือ `finalizer` ซึ่งเป็น!X()destructor แบบไม่กำหนด (nondeterministic destructor) ชนิดพิเศษที่ทำงานเป็นส่วนหนึ่งของกระบวนการเก็บขยะ (garbage collection ) ไวยากรณ์ destructor ของ C++ ~X()ยังมีอยู่สำหรับ managed object ด้วย และสะท้อนความหมายแบบ "ดั้งเดิม" ของ C++ ในเรื่องการทำลายแบบกำหนด (deterministic destruction) ได้ดีกว่า (นั่นคือ destructor ที่โค้ดของผู้ใช้สามารถเรียกได้ด้วย `destructor` delete)
ในรูปแบบพื้นฐานของ .NET โมเดลการทำลายแบบไม่แน่นอนจะเขียนทับFinalize()เมธอด protected ของคลาสหลักSystem::Objectในขณะที่โมเดลแบบแน่นอนจะถูกนำไปใช้ผ่านเมธอดSystem::IDisposableอินเทอร์เฟซDispose() (ซึ่งคอมไพเลอร์ C++/CLI จะแปลงตัวทำลายให้เป็น) อ็อบเจ็กต์จากโค้ด C# หรือ VB.NET ที่เขียนทับเมธอด Dispose สามารถถูกกำจัดด้วยตนเองใน C++/CLI deleteได้เช่นเดียวกับคลาส .NET ใน C++/CLI
เนมสเปซWikipedia :: ตัวอย่าง{// คลาสอ้างอิงC++/CLI MyClass { protected : ! MyClass (); // ตัวทำลายขั้นสุดท้าย (ตัวทำลายที่ไม่แน่นอน) (ใช้งานโดย Finalize()) public : MyClass (); // ตัวสร้าง~ MyClass (); // ตัวทำลาย (แน่นอน) (ใช้งานโดย IDisposable.Dispose()) static void Test () { MyClass automatic ; // ไม่ใช่แฮนเดิล ไม่มีการเริ่มต้น: คอมไพเลอร์เรียกตัวสร้างที่นี่MyClass ^ user = gcnew MyClass (); delete user ;// คอมไพเลอร์จะเรียกตัวทำลายของ automatic เมื่อ automatic หมดขอบเขต} };}การโอเวอร์โหลดผู้ปฏิบัติงาน
การโอเวอร์โหลดตัวดำเนินการทำงานในลักษณะเดียวกับมาตรฐาน C++ ทุกตัว*จะกลายเป็น `or` ^, ทุกตัว&จะกลายเป็น `or` %แต่ไวยากรณ์ส่วนที่เหลือยังคงเหมือนเดิม ยกเว้นส่วนเพิ่มเติมที่สำคัญ: สำหรับคลาส .NET การโอเวอร์โหลดตัวดำเนินการไม่เพียงแต่ใช้ได้กับคลาสเองเท่านั้น แต่ยังใช้ได้กับตัวอ้างอิงถึงคลาสเหล่านั้นด้วย คุณสมบัตินี้จำเป็นเพื่อให้คลาสอ้างอิงมีความหมายสำหรับการโอเวอร์โหลดตัวดำเนินการตามที่คาดหวังจากคลาสอ้างอิงของ .NET (ในทางกลับกัน นี่หมายความว่าสำหรับคลาสอ้างอิงของเฟรมเวิร์ก .NET การโอเวอร์โหลดตัวดำเนินการอ้างอิงมักจะถูกนำไปใช้โดยปริยายใน C++/CLI)
ตัวอย่างเช่น การเปรียบเทียบการอ้างอิงสตริงที่แตกต่างกันสองรายการ ( System::String^) ผ่านตัวดำเนินการ==จะให้ค่าจริงเมื่อใดก็ตามที่สตริงทั้งสองเท่ากัน อย่างไรก็ตาม การโอเวอร์โหลดตัวดำเนินการเป็นแบบคงที่ ดังนั้น การแปลงเป็นSystem::Object^จะลบความหมายของการโอเวอร์โหลดออกไป
การใช้เนมสเปซSystem ;// ผลกระทบของการโอเวอร์โหลดตัวดำเนินการอ้างอิงString ^ s1 = "abc" ; String ^ s2 = "ab" + "c" ; Object ^ o1 = s1 ; Object ^ o2 = s2 ; s1 == s2 ; // จริงo1 == o2 ; // เท็จความสามารถในการทำงานร่วมกัน
C++/CLI อนุญาตให้โปรแกรม C++ ใช้งานโปรแกรม C# ใน DLL ของ C# ได้[ 3 ]ในที่นี้#usingคำสั่งจะแสดงให้คอมไพเลอร์ทราบว่า DLL อยู่ที่ใดสำหรับข้อมูลเมตาการคอมไพล์ ตัวอย่างง่ายๆ นี้ไม่จำเป็นต้องมีการจัดเรียงข้อมูล
นำเข้า"stdafx.h" ;#ใช้ "Wikipedia.Examples.dll"using namespace System ; using namespace Wikipedia :: Examples ;int main ( array < String ^>^ args ) { double x = Class1 :: Add ( 40.1 , 1.9 ); return 0 ; }เนื้อหาซอร์สโค้ด C# ของไฟล์ Wikipedia.Examples.dll :
เนมสเปซWikipedia.Examples ;public class Class1 { public static double Add ( double a , double b ) { return a + b ; } }ตัวอย่างนี้แสดงวิธีการแปลงสตริงจากสตริง C++ ( std::string) ไปเป็นสตริง .NET ( System.String) แล้วแปลงกลับมาเป็นสตริง C++ อีกครั้ง การแปลงสตริงจะคัดลอกเนื้อหาของสตริงไปยังรูปแบบที่สามารถใช้งานได้ในสภาพแวดล้อมต่างๆ
import <string> ; import <iostream> ; import < msclr \ marshal_cppstd.h > ; import " stdafx.h " ;#ใช้ "Wikipedia.Examples.dll"// เนมสเปซ std ไม่ได้นำเข้าเพื่อแยกความแตกต่างจากประเภท .NET using namespace System ; using namespace Wikipedia :: Examples ;int main () { std :: string s = "I am cat" ; String ^ clrString = msclr :: interop :: marshal_as < String ^> ( s ); // สตริงที่ใช้ได้จาก C# (System::String) String ^ t = Class1 :: Process ( clrString ); // เรียกฟังก์ชัน C# std :: string cppString = msclr :: interop :: marshal_as < std :: string > ( t ); // สตริงที่ใช้ได้จาก C++ std :: cout << "Hello, C++/C# Interop!" << std :: endl ; std :: cout << cppString << std :: endl ; return 0 ; }โค้ด C# นี้ไม่ได้คำนึงถึงภาษา C++ แต่อย่างใด
เนมสเปซWikipedia.Examples ;public class Class1 { public static string process ( string a ) { return a . Replace ( "cat" , "dog" ) + " with a tail" ; } }การทำงานร่วมกันระหว่าง C++ และ C# จึงทำให้ C++ สามารถเข้าถึงคุณสมบัติทั้งหมดของ .NET ได้ง่ายขึ้น
ซี++/ซีเอ็กซ์
C++/CXที่กำหนดเป้าหมายไปที่WinRTแม้ว่าจะสร้างโค้ดที่ไม่ได้รับการจัดการทั้งหมด แต่ก็ยืมไวยากรณ์refและ^สำหรับส่วนประกอบที่มีการนับการอ้างอิงของ WinRT ซึ่งคล้ายกับ"อ็อบเจ็กต์" ของ COM [ 4 ]
ดูเพิ่มเติม
- ซี++/ซีเอ็กซ์
- ซี++/วินอาร์ที
- GNU Compiler for Javaซึ่งรองรับการทำงานร่วมกันระหว่าง C++ และ Java
- อินเทอร์เฟซเนทีฟ Java
อ่านเพิ่มเติม
- ซัตเตอร์, เฮิร์บ (23 พฤศจิกายน 2003). "คำสำคัญ C++/CLI: เบื้องหลัง" . บล็อกของเฮิร์บ ซัตเตอร์ . ไมโครซอฟต์ . เก็บถาวรจากต้นฉบับเมื่อ 9 พฤศจิกายน 2007.
- ซัตเตอร์, เฮิร์บ (24 กุมภาพันธ์ 2549). "เหตุผลในการออกแบบสำหรับ C++/CLI" (PDF) . จัดพิมพ์เอง .
- Stroustrup, Bjarne (23 กรกฎาคม 2021). "คุณคิดอย่างไรเกี่ยวกับ C++/CLI?"คำถามที่พบบ่อยของ Bjarne Stroustrup . เผยแพร่เอง .
- Lippman, Stanley . "Pure C++: Hello, C++/CLI" . MSDN Magazine . 21 (3). Microsoft . เก็บถาวรจากต้นฉบับเมื่อวันที่ 5 กุมภาพันธ์ 2551
- Lippman, Stanley (5 สิงหาคม 2547). "เหตุใด C++/CLI จึงรองรับทั้งเทมเพลตสำหรับประเภท CLI และกลไก Generic ของ CLI"บล็อกของ Stan Lippman . Microsoft . เก็บถาวรจากต้นฉบับเมื่อวันที่ 7 ตุลาคม 2550
ลิงก์ภายนอก
- เว็บไซต์อย่างเป็นทางการ
- สิทธิบัตรเกี่ยวกับช่องว่างในคำหลัก
สรุปเนื้อหา
ข้อมูลสำคัญจากบทความ
ข้อมูลสำคัญเกี่ยวกับ ซี++/ซีแอลไอ
C++/CLIเป็นรูปแบบหนึ่งของภาษาการเขียนโปรแกรมC++ ซึ่งได้รับการดัดแปลงสำหรับโครงสร้างพื้นฐานภาษาทั่วไป (Common Language Infrastructure ) เป็นส่วนหนึ่งของVisual Studio 2005...
การเปลี่ยนแปลงไวยากรณ์
ควรพิจารณา C++/CLI ว่าเป็นภาษาเฉพาะของตัวเอง (เช่น มีชุดคีย์เวิร์ดใหม่) แทนที่จะเป็น Managed C++ (MC++) ซึ่งเป็นส่วนขยายของ C++ (โดยคีย์เวิร์ดที่ไม่เป็นมาตรฐานจะถูกเขียนในรูปแบบ ` ` __gc หรือ ` __value `) ด้วยเหตุนี้...
ด้ามจับ
ใน MC++ มี พอยเตอร์ อยู่สองประเภทที่แตกต่างกัน คือ __nogc พอยเตอร์แบบปกติของ C++ และ __gc พอยเตอร์ที่ทำงานกับประเภทอ้างอิงของ .NET อย่างไรก็ตาม ใน C++/CLI พอยเตอร์ประเภทเดียวที่มีอยู่คือพอยเตอร์แบบปกติของ C++ ในขณะที่ประเภทอ้างอิงของ .
การติดตามข้อมูลอ้างอิง
ใน C++/CLI การ อ้างอิงแบบติดตาม (tracking reference) คือตัวจัดการของตัวแปรที่ส่งผ่านโดยการอ้างอิง (passed-by-reference variable) แนวคิดคล้ายกับการใช้การ อ้างอิงไปยังตัวชี้ *& (reference to the pointer) ใน C++ มาตรฐาน และ (ในการประกาศฟังก์ชัน) สอดคล้องกับ ref...