Megosztás a következőn keresztül:


Mi az a COM-felület?

Ha ismeri a C#-t vagy a Java-t, a felületeknek ismerős fogalomnak kell lenniük. A felület olyan metódusokat határoz meg, amelyeket egy objektum támogathat anélkül, hogy bármit diktálna a megvalósítással kapcsolatban. Az interfész egyértelmű határt jelöl a metódust meghívó kód és a metódust megvalósító kód között. Számítástechnika szempontjából a hívó el van különítve a megvalósítástól.

ábrán egy objektum és egy alkalmazás közötti határvonal látható,

A C++-ban a felület legközelebbi megfelelője egy tiszta virtuális osztály, vagyis egy olyan osztály, amely csak tiszta virtuális metódusokat és más tagokat tartalmaz. Íme egy hipotetikus példa egy interfészre:

// The following is not actual COM.

// Pseudo-C++:

interface IDrawable
{
    void Draw();
};

A példa lényege, hogy egyes grafikus tárak objektumkészlete rajzolható. A IDrawable felület határozza meg azokat a műveleteket, amelyeket minden rajzolható objektumnak támogatnia kell. (Konvenció szerint a felületnevek az "I" betűvel kezdődnek.) Ebben a példában a IDrawable felület egyetlen műveletet határoz meg: Draw.

Minden interfész absztrakt , mivel a program nem hozhat létre IDrawable objektumpéldányt. Egy példa erre, hogy a következő kód nem fordulna le.

IDrawable draw;
draw.Draw();

Ehelyett a grafikus kódtár olyan objektumokat biztosít, amelyek implementálják a IDrawable interfészt. Előfordulhat például, hogy a tár alakzatobjektumot biztosít az alakzatok rajzoláshoz, a képekhez pedig bitképobjektumot. A C++-ban ez egy általános absztrakt alaposztály öröklésével történik:

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

A Shape és Bitmap osztályok két különböző típusú rajzolható objektumot határoznak meg. Minden osztály örökli a IDrawable, és saját implementációt biztosít a Draw metódushoz. Természetesen a két megvalósítás jelentősen eltérhet. A Shape::Draw metódus például sorokat raszterizálhat, míg Bitmap::Draw képpontokból álló tömböt raszterizálhat.

A grafikus kódtárat használó programok IDrawable mutatókkal manipulálnák Shape és Bitmap objektumokat, ahelyett, hogy közvetlenül Shape vagy Bitmap mutatókat használnának.

IDrawable *pDrawable = CreateTriangleShape();

if (pDrawable)
{
    pDrawable->Draw();
}

Íme egy példa, amely végighalad egy IDrawable mutatókat tartalmazó tömbön. A tömb alakzatok, bitképek és egyéb grafikus objektumok heterogén választékát tartalmazhatja, feltéve, hogy a tömb minden objektuma örökli IDrawable.

void DrawSomeShapes(IDrawable **drawableArray, size_t count)
{
    for (size_t i = 0; i < count; i++)
    {
        drawableArray[i]->Draw();
    }
}

A COM egyik legfontosabb pontja, hogy a hívó kód soha nem látja a származtatott osztály típusát. Más szóval soha nem deklarálna Shape vagy Bitmap típusú változót a kódban. Az alakzatokon és bitképeken végzett összes művelet IDrawable mutatókkal történik. Ily módon a COM szigorú elkülönítést tart fenn az interfész és a megvalósítás között. A Shape és Bitmap osztályok implementálási részletei – például a hibák kijavítása vagy új képességek hozzáadása – a hívókód módosítása nélkül változhatnak.

A C++ implementációban az interfészek osztály vagy struktúra használatával vannak deklarálva.

Jegyzet

A jelen témakörben szereplő példakódok általános fogalmakat, nem pedig valós gyakorlatot közvetítenek. Az új COM-felületek definiálása meghaladja a sorozat hatókörét, de közvetlenül nem határozna meg felületet egy fejlécfájlban. Ehelyett a COM-felület egy interfészdefiníciós nyelv (IDL) nevű nyelv használatával van definiálva. Az IDL-fájlt egy IDL-fordító dolgozza fel, amely egy C++ fejlécfájlt hoz létre.

class IDrawable
{
public:
    virtual void Draw() = 0;
};

A COM használatakor fontos megjegyezni, hogy a felületek nem objektumok. Ezek olyan metódusok gyűjteményei, amelyeket az objektumoknak implementálniuk kell. Több objektum is megvalósíthatja ugyanazt az interfészt, ahogy az Shape és Bitmap példákban is látható. Ezenkívül egy objektum több interfészt is implementálhat. A grafikus tár például meghatározhat egy ISerializable nevű felületet, amely támogatja a grafikus objektumok mentését és betöltését. Most vegye figyelembe a következő osztálydeklarációkat:

// 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
{
    ...
};

Ebben a példában a Bitmap osztály implementálja a ISerializable. A program ezzel a módszerrel mentheti vagy betöltheti a bitképet. A Shape osztály azonban nem implementálja a ISerializable, ezért nem teszi elérhetővé ezt a funkciót. Az alábbi ábra az öröklési kapcsolatokat mutatja be ebben a példában.

felületöröklést ábrázoló ábra, ahol az alakzat és bitképosztályok az idrawable-ra mutatnak, de csak a bitmap az iserializable-ra

Ez a szakasz megvizsgálta az interfészek elméleti alapjait, de eddig nem láttunk tényleges COM-kódot. Első lépésként minden COM-alkalmazásnak el kell végeznie a következőt: Inicializálja a COM-kódtárat.

Következő

COM-kódtár inicializálása