Kommentar
Å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.
Abstrakta klasser fungerar som uttryck för allmänna begrepp som mer specifika klasser kan härledas från. Du kan inte skapa ett objekt av en abstrakt klasstyp. Du kan dock använda pekare och referenser till abstrakta klasstyper.
Du skapar en abstrakt klass genom att deklarera minst en ren virtuell medlemsfunktion. Det är en virtuell funktion som deklareras med hjälp av syntaxen för ren specificerare (= 0). Klasser som härleds från den abstrakta klassen måste implementera den rena virtuella funktionen, annars är även de abstrakta klasser.
Överväg exemplet som visas i Virtuella funktioner. Avsikten med klassen Account är att tillhandahålla allmänna funktioner, men objekt av typen Account är för allmänna för att vara användbara. Det innebär att Account är en bra kandidat för en abstrakt klass:
// 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;
};
Den enda skillnaden mellan den här deklarationen och den föregående är den som PrintBalance deklareras med den rena specificeraren (= 0).
Begränsningar för abstrakta klasser
Abstrakta klasser kan inte användas för:
Variabler eller medlemsdata
Argumenttyper
Funktionsreturtyper
Typer av explicita konverteringar
Om konstruktorn för en abstrakt klass anropar en ren virtuell funktion, antingen direkt eller indirekt, är resultatet odefinierat. Konstruktorer och destruktorer för abstrakta klasser kan dock anropa andra medlemsfunktioner.
Definierade rena virtuella funktioner
Rena virtuella funktioner i abstrakta klasser kan definieras eller ha en implementering. Du kan bara anropa sådana funktioner med hjälp av den fullständigt kvalificerade syntaxen:
abstract-class-name::function-name()
Definierade rena virtuella funktioner är användbara när du utformar klasshierarkier vars basklasser innehåller rena virtuella destructors. Det beror på att basklassförstörare alltid anropas under objektförstörelse. Tänk på följande exempel:
// 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
}
Exemplet visar hur ett Microsoft-kompilatortillägg låter dig lägga till en infogad definition i ren virtuell ~base(). Du kan också definiera den utanför klassen med hjälp base::~base() {}av .
När objektet aDerived hamnar utanför omfånget anropas destrukteraren för klassen derived . Kompilatorn genererar kod för att implicit anropa destruatorn för klassen base efter derived destruatorn. Den tomma implementeringen för den rena virtuella funktionen ~base säkerställer att åtminstone en viss implementering finns för funktionen. Utan den genererar länkaren ett olöst externt symbolfel för det implicita anropet.
Anmärkning
I föregående exempel anropas den rena virtuella funktionen base::~base implicit från derived::~derived. Det går också att anropa rena virtuella funktioner explicit med hjälp av ett fullständigt kvalificerat medlemsfunktionsnamn. Sådana funktioner måste ha en implementering, eller så resulterar anropet i ett fel vid länktiden.