Sdílet prostřednictvím


Abstraktní třídy (C++)

Abstraktní třídy fungují jako výrazy obecných konceptů, ze kterých lze odvodit konkrétnější třídy. Objekt abstraktního typu třídy nelze vytvořit. K abstraktním typům tříd ale můžete použít ukazatele a odkazy.

Abstraktní třídu vytvoříte deklarací alespoň jedné čistě virtuální členské funkce. To je virtuální funkce deklarovaná pomocí syntaxe čistého specifikátoru (= 0). Třídy odvozené z abstraktní třídy musí implementovat čistě virtuální funkci, nebo jsou také abstraktní třídy.

Představte si příklad uvedený ve virtuálních funkcích. Účelem třídy Account je poskytovat obecné funkce, ale objekty typu Account jsou příliš obecné, aby byly užitečné. To znamená Account , že je vhodným kandidátem pro abstraktní třídu:

// deriv_AbstractClasses.cpp
// compile with: /LD
class Account {
public:
   Account( double d );   // Constructor.
   virtual double GetBalance();   // Obtain balance.
   virtual void PrintBalance() = 0;   // Pure virtual function.
private:
    double _balance;
};

Jediným rozdílem mezi touto deklarací a předchozím je deklarován PrintBalance čistým specifikátorem (= 0).

Omezení abstraktních tříd

Abstraktní třídy nelze použít pro:

  • Proměnné nebo členská data

  • Typy argumentů

  • Návratové typy funkcí

  • Typy explicitních převodů

Pokud konstruktor abstraktní třídy volá čistě virtuální funkci přímo nebo nepřímo, výsledek není definován. Konstruktory a destruktory abstraktních tříd však mohou volat ostatní členské funkce.

Definované čistě virtuální funkce

Čistě virtuální funkce v abstraktních třídách lze definovat nebo mají implementaci. Tyto funkce můžete volat pouze pomocí plně kvalifikované syntaxe:

abstract-class-name::function-name()

Definované čistě virtuální funkce jsou užitečné při návrhu hierarchií tříd, jejichž základní třídy zahrnují čistě virtuální destruktory. Je to proto, že destruktory základní třídy se vždy volají během zničení objektu. Představte si následující příklad:

// deriv_RestrictionsOnUsingAbstractClasses.cpp
// Declare an abstract base class with a pure virtual destructor.
// It's the simplest possible abstract class.
class base
{
public:
    base() {}
    // To define the virtual destructor outside the class:
    virtual ~base() = 0;
    // Microsoft-specific extension to define it inline:
//  virtual ~base() = 0 {};
};

base::~base() {} // required if not using Microsoft extension

class derived : public base
{
public:
    derived() {}
    ~derived() {}
};

int main()
{
    derived aDerived; // destructor called when it goes out of scope
}

Příklad ukazuje, jak rozšíření kompilátoru Společnosti Microsoft umožňuje přidat vloženou definici k čisté virtuální ~base(). Můžete jej také definovat mimo třídu pomocí base::~base() {}.

Když objekt aDerived zmizí z oboru, je volána destruktor pro třídu derived . Kompilátor generuje kód, který implicitně volá destruktor třídy base za derived destruktorem. Prázdná implementace čistě virtuální funkce ~base zajišťuje, že pro funkci existuje alespoň některá implementace. Bez něj linker vygeneruje nevyřešenou chybu externího symbolu pro implicitní volání.

Poznámka:

V předchozím příkladu je čistě virtuální funkce base::~base zavolána implicitně z funkce derived::~derived. Je také možné volat čistě virtuální funkce explicitně pomocí plně kvalifikovaného názvu členské funkce. Takové funkce musí mít implementaci nebo výsledkem volání je chyba v době propojení.

Viz také

Dědičnost