Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Als u C# of Java kent, moeten interfaces een bekend concept zijn. Een interface definieert een set methoden die een object kan ondersteunen, zonder iets over de implementatie te dicteren. De interface markeert een duidelijke grens tussen code die een methode aanroept en de code waarmee de methode wordt geïmplementeerd. In computerwetenschappen wordt de aanroeper losgekoppeld van de implementatie.
In C++is het dichtstbijzijnde equivalent van een interface een pure virtuele klasse, dat wil gezegd, een klasse die alleen pure virtuele methoden en geen andere leden bevat. Hier volgt een hypothetisch voorbeeld van een interface:
// The following is not actual COM.
// Pseudo-C++:
interface IDrawable
{
void Draw();
};
Het idee van dit voorbeeld is dat een set objecten in een bepaalde grafische bibliotheek kan worden getekend. De IDrawable-interface definieert de bewerkingen die elk tekenbaar object moet ondersteunen. (Volgens conventie beginnen interfacenamen met 'I'.) In dit voorbeeld definieert de IDrawable-interface één bewerking: Draw.
Alle interfaces zijn abstracte, zodat een programma geen exemplaar van een IDrawable object als zodanig kan maken. De volgende code zou bijvoorbeeld niet worden gecompileerd.
IDrawable draw;
draw.Draw();
In plaats daarvan biedt de grafische bibliotheek objecten die implementeren de IDrawable-interface. De bibliotheek kan bijvoorbeeld een shapeobject bieden voor het tekenen van vormen en een bitmapobject voor het tekenen van afbeeldingen. In C++wordt dit gedaan door het overnemen van een algemene abstracte basisklasse:
class Shape : public IDrawable
{
public:
virtual void Draw(); // Override Draw and provide implementation.
};
class Bitmap : public IDrawable
{
public:
virtual void Draw(); // Override Draw and provide implementation.
};
De klassen Shape en Bitmap definiëren twee verschillende typen tekenbare objecten. Elke klasse neemt over van IDrawable en biedt een eigen implementatie van de Draw methode. Uiteraard kunnen de twee implementaties aanzienlijk verschillen. De methode Shape::Draw kan bijvoorbeeld een set lijnen rasteren, terwijl Bitmap::Draw een matrix met pixels zou bliten.
Een programma dat deze grafische bibliotheek gebruikt, zou Shape en Bitmap objecten bewerken via IDrawable aanwijzers, in plaats van rechtstreeks Shape of Bitmap aanwijzers te gebruiken.
IDrawable *pDrawable = CreateTriangleShape();
if (pDrawable)
{
pDrawable->Draw();
}
Hier volgt een voorbeeld dat een tabel met IDrawable pointers doorloopt. De matrix kan een heterogene reeks vormen, bitmaps en andere grafische objecten bevatten, zolang elk object in de matrix IDrawableover neemt.
void DrawSomeShapes(IDrawable **drawableArray, size_t count)
{
for (size_t i = 0; i < count; i++)
{
drawableArray[i]->Draw();
}
}
Een belangrijk punt over COM is dat de aanroepende code nooit het type van de afgeleide klasse ziet. Met andere woorden, u zou nooit een variabele van het type Shape of Bitmap in uw code declareren. Alle bewerkingen op shapes en bitmaps worden uitgevoerd met behulp van IDrawable aanwijzers. Op deze manier onderhoudt COM een strikte scheiding tussen interface en implementatie. De implementatiedetails van de Shape- en Bitmap-klassen kunnen veranderen, bijvoorbeeld om bugs op te lossen of nieuwe mogelijkheden toe te voegen, zonder dat de aanroepende code wordt gewijzigd.
In een C++-implementatie worden interfaces gedeclareerd met behulp van een klasse of structuur.
Notitie
De codevoorbeelden in dit onderwerp zijn bedoeld om algemene concepten over te brengen, niet praktijk. Het definiëren van nieuwe COM-interfaces valt buiten het bereik van deze reeks, maar u zou geen interface rechtstreeks in een headerbestand definiëren. In plaats daarvan wordt een COM-interface gedefinieerd met behulp van een taal met de naam Interface Definition Language (IDL). Het IDL-bestand wordt verwerkt door een IDL-compiler, waarmee een C++-headerbestand wordt gegenereerd.
class IDrawable
{
public:
virtual void Draw() = 0;
};
Wanneer u met COM werkt, is het belangrijk om te onthouden dat interfaces geen objecten zijn. Het zijn verzamelingen methoden die objecten moeten implementeren. Verschillende objecten kunnen dezelfde interface implementeren, zoals wordt weergegeven met de Shape en Bitmap voorbeelden. Bovendien kan één object verschillende interfaces implementeren. De grafische bibliotheek kan bijvoorbeeld een interface definiëren met de naam ISerializable die ondersteuning biedt voor het opslaan en laden van grafische objecten. Overweeg nu de volgende klassedeclaraties:
// An interface for serialization.
class ISerializable
{
public:
virtual void Load(PCWSTR filename) = 0; // Load from file.
virtual void Save(PCWSTR filename) = 0; // Save to file.
};
// Declarations of drawable object types.
class Shape : public IDrawable
{
...
};
class Bitmap : public IDrawable, public ISerializable
{
...
};
In dit voorbeeld implementeert de Bitmap klasse ISerializable. Het programma kan deze methode gebruiken om de bitmap op te slaan of te laden. De Shape-klasse implementeert echter geen ISerializable, zodat deze functionaliteit niet beschikbaar wordt gesteld. In het volgende diagram ziet u de overnamerelaties in dit voorbeeld.
In deze sectie is de conceptuele basis van interfaces onderzocht, maar tot nu toe hebben we geen werkelijke COM-code gezien. We beginnen met het eerste wat elke COM-toepassing moet doen: Initialiseer de COM-bibliotheek.