Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
STL/CLR-containrar som list och map implementeras som mall ref-klasser. Eftersom C++-mallar instansieras vid kompileringstillfället är två mallklasser som har exakt samma signatur men som finns i olika sammansättningar faktiskt olika typer. Det innebär att mallklasser inte kan användas över sammansättningsgränser.
För att göra delning mellan sammansättningar möjlig implementerar STL/CLR-containrar det generiska gränssnittet ICollection<T>. Med det här allmänna gränssnittet kan alla språk som stöder generiska objekt, inklusive C++, C#och Visual Basic, komma åt STL/CLR-containrar.
Det här avsnittet visar hur du visar elementen i flera STL/CLR-containrar som skrivits i en C++-sammansättning med namnet StlClrClassLibrary. Vi visar två sammansättningar för att komma åt StlClrClassLibrary. Den första sammansättningen skrivs i C++, och den andra i C#.
Om båda sammansättningarna är skrivna i C++, kan du komma åt det allmänna gränssnittet för en container med hjälp av dess generic_container typedef. Om du till exempel har en container av typen cliext::vector<int>är dess allmänna gränssnitt: cliext::vector<int>::generic_container. På samma sätt kan du hämta en iterator över det generiska gränssnittet genom att använda generic_iterator typedef, som i: cliext::vector<int>::generic_iterator.
Eftersom dessa typedefs deklareras i C++-huvudfiler kan sammansättningar som skrivits på andra språk inte använda dem. För att få åtkomst till det allmänna gränssnittet för cliext::vector<int> i C# eller något annat .NET-språk använder du System.Collections.Generic.ICollection<int>därför . Om du vill iterera över den här samlingen använder du en foreach loop.
I följande tabell visas det allmänna gränssnitt som varje STL/CLR-container implementerar:
| STL/CLR-container | Allmänt gränssnitt |
|---|---|
deque<T> |
ICollection<T> |
hash_map<K, V> |
IDictionary<K, V> |
hash_multimap<K, V> |
IDictionary<K, V> |
hash_multiset<T> |
ICollection<T> |
hash_set<T> |
ICollection<T> |
list<T> |
ICollection<T> |
map<K, V> |
IDictionary<K, V> |
multimap<K, V> |
IDictionary<K, V> |
multiset<T> |
ICollection<T> |
set<T> |
ICollection<T> |
vector<T> |
ICollection<T> |
Anmärkning
queueEftersom containrarna , priority_queueoch stack inte stöder iteratorer implementerar de inte allmänna gränssnitt och kan inte nås mellan sammansättningar.
Exempel 1
Beskrivning
I det här exemplet deklarerar vi en C++-klass som innehåller privata STL/CLR-medlemsdata. Sedan deklarerar vi offentliga metoder för att bevilja åtkomst till klassens privata samlingar. Vi gör det på två olika sätt, en för C++-klienter och en för andra .NET-klienter.
Kod
// StlClrClassLibrary.h
#pragma once
#include <cliext/deque>
#include <cliext/list>
#include <cliext/map>
#include <cliext/set>
#include <cliext/stack>
#include <cliext/vector>
using namespace System;
using namespace System::Collections::Generic;
using namespace cliext;
namespace StlClrClassLibrary {
public ref class StlClrClass
{
public:
StlClrClass();
// These methods can be called by a C++ class
// in another assembly to get access to the
// private STL/CLR types defined below.
deque<wchar_t>::generic_container ^GetDequeCpp();
list<float>::generic_container ^GetListCpp();
map<int, String ^>::generic_container ^GetMapCpp();
set<double>::generic_container ^GetSetCpp();
vector<int>::generic_container ^GetVectorCpp();
// These methods can be called by a non-C++ class
// in another assembly to get access to the
// private STL/CLR types defined below.
ICollection<wchar_t> ^GetDequeCs();
ICollection<float> ^GetListCs();
IDictionary<int, String ^> ^GetMapCs();
ICollection<double> ^GetSetCs();
ICollection<int> ^GetVectorCs();
private:
deque<wchar_t> ^aDeque;
list<float> ^aList;
map<int, String ^> ^aMap;
set<double> ^aSet;
vector<int> ^aVector;
};
}
Exempel 2
Beskrivning
I det här exemplet implementerar vi klassen som deklarerats i Exempel 1. För att klienter ska kunna använda det här klassbiblioteket använder vi manifestverktyget mt.exe för att bädda in manifestfilen i DLL-filen. Mer information finns i kodkommentarna.
Mer information om manifestverktyget och sammansättningar sida vid sida finns i Skapa C/C++-isolerade program och sida vid sida sammansättningar.
Kod
// StlClrClassLibrary.cpp
// compile with: /clr /LD /link /manifest
// post-build command: (attrib -r StlClrClassLibrary.dll & mt /manifest StlClrClassLibrary.dll.manifest /outputresource:StlClrClassLibrary.dll;#2 & attrib +r StlClrClassLibrary.dll)
#include "StlClrClassLibrary.h"
namespace StlClrClassLibrary
{
StlClrClass::StlClrClass()
{
aDeque = gcnew deque<wchar_t>();
aDeque->push_back(L'a');
aDeque->push_back(L'b');
aList = gcnew list<float>();
aList->push_back(3.14159f);
aList->push_back(2.71828f);
aMap = gcnew map<int, String ^>();
aMap[0] = "Hello";
aMap[1] = "World";
aSet = gcnew set<double>();
aSet->insert(3.14159);
aSet->insert(2.71828);
aVector = gcnew vector<int>();
aVector->push_back(10);
aVector->push_back(20);
}
deque<wchar_t>::generic_container ^StlClrClass::GetDequeCpp()
{
return aDeque;
}
list<float>::generic_container ^StlClrClass::GetListCpp()
{
return aList;
}
map<int, String ^>::generic_container ^StlClrClass::GetMapCpp()
{
return aMap;
}
set<double>::generic_container ^StlClrClass::GetSetCpp()
{
return aSet;
}
vector<int>::generic_container ^StlClrClass::GetVectorCpp()
{
return aVector;
}
ICollection<wchar_t> ^StlClrClass::GetDequeCs()
{
return aDeque;
}
ICollection<float> ^StlClrClass::GetListCs()
{
return aList;
}
IDictionary<int, String ^> ^StlClrClass::GetMapCs()
{
return aMap;
}
ICollection<double> ^StlClrClass::GetSetCs()
{
return aSet;
}
ICollection<int> ^StlClrClass::GetVectorCs()
{
return aVector;
}
}
Exempel 3
Beskrivning
I det här exemplet skapar vi en C++-klient som använder klassbiblioteket som skapats i exempel 1 och 2. Den här klienten använder generic_container typedefs för STL/CLR-containrar för att iterera över containrarna och för att visa deras innehåll.
Kod
// CppConsoleApp.cpp
// compile with: /clr /FUStlClrClassLibrary.dll
#include <cliext/deque>
#include <cliext/list>
#include <cliext/map>
#include <cliext/set>
#include <cliext/vector>
using namespace System;
using namespace StlClrClassLibrary;
using namespace cliext;
int main(array<System::String ^> ^args)
{
StlClrClass theClass;
Console::WriteLine("cliext::deque contents:");
deque<wchar_t>::generic_container ^aDeque = theClass.GetDequeCpp();
for each (wchar_t wc in aDeque)
{
Console::WriteLine(wc);
}
Console::WriteLine();
Console::WriteLine("cliext::list contents:");
list<float>::generic_container ^aList = theClass.GetListCpp();
for each (float f in aList)
{
Console::WriteLine(f);
}
Console::WriteLine();
Console::WriteLine("cliext::map contents:");
map<int, String ^>::generic_container ^aMap = theClass.GetMapCpp();
for each (map<int, String ^>::value_type rp in aMap)
{
Console::WriteLine("{0} {1}", rp->first, rp->second);
}
Console::WriteLine();
Console::WriteLine("cliext::set contents:");
set<double>::generic_container ^aSet = theClass.GetSetCpp();
for each (double d in aSet)
{
Console::WriteLine(d);
}
Console::WriteLine();
Console::WriteLine("cliext::vector contents:");
vector<int>::generic_container ^aVector = theClass.GetVectorCpp();
for each (int i in aVector)
{
Console::WriteLine(i);
}
Console::WriteLine();
return 0;
}
Utgång
cliext::deque contents:
a
b
cliext::list contents:
3.14159
2.71828
cliext::map contents:
0 Hello
1 World
cliext::set contents:
2.71828
3.14159
cliext::vector contents:
10
20
Exempel 4
Beskrivning
I det här exemplet skapar vi en C#-klient som använder klassbiblioteket som skapats i exempel 1 och 2. Den här klienten använder ICollection<T> metoderna för STL/CLR-containrar för att iterera över containrarna och för att visa deras innehåll.
Kod
// CsConsoleApp.cs
// compile with: /r:Microsoft.VisualC.STLCLR.dll /r:StlClrClassLibrary.dll /r:System.dll
using System;
using System.Collections.Generic;
using StlClrClassLibrary;
using cliext;
namespace CsConsoleApp
{
class Program
{
static int Main(string[] args)
{
StlClrClass theClass = new StlClrClass();
Console.WriteLine("cliext::deque contents:");
ICollection<char> iCollChar = theClass.GetDequeCs();
foreach (char c in iCollChar)
{
Console.WriteLine(c);
}
Console.WriteLine();
Console.WriteLine("cliext::list contents:");
ICollection<float> iCollFloat = theClass.GetListCs();
foreach (float f in iCollFloat)
{
Console.WriteLine(f);
}
Console.WriteLine();
Console.WriteLine("cliext::map contents:");
IDictionary<int, string> iDict = theClass.GetMapCs();
foreach (KeyValuePair<int, string> kvp in iDict)
{
Console.WriteLine("{0} {1}", kvp.Key, kvp.Value);
}
Console.WriteLine();
Console.WriteLine("cliext::set contents:");
ICollection<double> iCollDouble = theClass.GetSetCs();
foreach (double d in iCollDouble)
{
Console.WriteLine(d);
}
Console.WriteLine();
Console.WriteLine("cliext::vector contents:");
ICollection<int> iCollInt = theClass.GetVectorCs();
foreach (int i in iCollInt)
{
Console.WriteLine(i);
}
Console.WriteLine();
return 0;
}
}
}
Utgång
cliext::deque contents:
a
b
cliext::list contents:
3.14159
2.71828
cliext::map contents:
0 Hello
1 World
cliext::set contents:
2.71828
3.14159
cliext::vector contents:
10
20