กลับไปหน้าบทความ

อ่าน 5 นาที

ซี++/ซีแอลไอ

มาตรฐานเอคม่า/เปลี่ยนทางจากชื่ออื่น

C++/CLIเป็นรูปแบบหนึ่งของภาษาการเขียนโปรแกรมC++ ซึ่งได้รับการดัดแปลงสำหรับโครงสร้างพื้นฐานภาษาทั่วไป (Common Language Infrastructure ) เป็นส่วนหนึ่งของVisual Studio 2005...

ซี++/ซีแอลไอ

ซี++/ซีแอลไอ
กระบวนทัศน์มีโครงสร้าง , เชิงคำสั่ง , เชิงวัตถุ
ตระกูลซี
ออกแบบโดยไมโครซอฟต์
นักพัฒนาไมโครซอฟต์
ปรากฏครั้งแรก2548 ( 2005 )
แพลตฟอร์มโครงสร้างพื้นฐานภาษาทั่วไป
เว็บไซต์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 ]

ดูเพิ่มเติม

อ่านเพิ่มเติม

  • ซัตเตอร์, เฮิร์บ (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
  • เว็บไซต์อย่างเป็นทางการ
  • สิทธิบัตรเกี่ยวกับช่องว่างในคำหลัก
ดึงข้อมูลมาจาก " https://en.wikipedia.org/w/index.php?title=C%2B%2B/CLI&oldid=1359583074 "

สรุปเนื้อหา

ข้อมูลสำคัญจากบทความ

ข้อมูลสำคัญเกี่ยวกับ ซี++/ซีแอลไอ

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...