12 Stimmen

Abstrakte Klasse ohne abstrakte Methoden

Ist es möglich, eine Klasse in C++ abstrakt zu machen, ohne abstrakte Methoden zu deklarieren? Derzeit habe ich eine Sprite-Klasse mit einer StaticSprite- und einer DynamicSprite-Unterklasse. Ich würde die Klasse Sprite gerne abstrakt machen.

Das Problem ist, dass es keine gemeinsamen Methoden gibt. Nun, StaticSprite und DynamicSprite könnten sich eine draw()-Methode teilen, aber die Parameter dieser Methode sind unterschiedlich, so dass dies keine Option ist.

Ich danke Ihnen!

EDIT: Hier ist der Code, um zu zeigen, was ich zu tun versuche:

Sprite:

class Sprite
{
    public:
        Sprite(HINSTANCE hAppInst, int imageID, int maskID);
        ~Sprite();

    protected:
        HINSTANCE hAppInst;
        HBITMAP hImage;
        HBITMAP hMask;
        BITMAP imageBM;
        BITMAP maskBM;
        HDC hSpriteDC;
};

Statik-Sprit:

class StaticSprite : public Sprite
{
    public:
        StaticSprite(HINSTANCE hAppInst, int imageID, int maskID);
        ~StaticSprite();

        void draw(Position* pos, HDC hBackbufferDC);
};

Dynamischer Spruch:

class DynamicSprite : public Sprite
{
    public:
        DynamicSprite(HINSTANCE hAppInst, int imageID, int maskID);
        ~DynamicSprite();

        void draw(HDC hBackbufferDC);
};

Wie Sie sehen, ist es nutzlos, ein Sprite-Objekt zu erstellen, also möchte ich diese Klasse abstrakt machen. Aber ich kann draw() nicht abstrakt machen, da es verschiedene Parameter verwendet.

19voto

Tugrul Ates Punkte 8990

Sie können Ihren Destruktor als rein virtuell deklarieren, da alle Klassen über einen solchen verfügen.

class AbstractClass
{
public:
    virtual ~AbstractClass() = 0 ;
} ;

Sie müssen diesen Destruktor jedoch an anderer Stelle definieren.

AbstractClass::~AbstractClass() {}

15voto

Randolpho Punkte 54011

Wenn die Klasse nichts tut und nichts bereitstellt und nur als Marker existiert, gibt es keinen Grund, sich darüber Gedanken zu machen, ob sie abstrakt ist oder nicht. Dies ist im Grunde genommen kein Problem.

Wenn Sie unbedingt sicherstellen wollen, dass ein Objekt niemals instanziiert wird, es sei denn im Kontext der Vererbung, verwenden Sie geschützte Konstrukteure .

Bitte vermeiden Sie es, einen rein virtuellen Destruktor zu erstellen. Auf diese Weise liegt der Wahnsinn.

3voto

Cthutu Punkte 8400

Nein, gibt es nicht.

Das können Sie natürlich verwenden:

class Sprite
{
};

aber der Compiler wird sich natürlich nicht beschweren, wenn Sie versuchen, eine Instanz davon zu erzeugen.

Sie können einen rein virtuellen Destruktor hinzufügen:

class Sprite
{
public:
    virtual ~Sprite () = 0;
};

oder Sie können den Konstruktor schützen und die Instanziierung stoppen:

class Sprite
{
protected:
    Sprite ();
};

3voto

fizzer Punkte 13343

Unter den besonderen Umständen Ihrer Stelle sollten Sie eine private Erbschaft in Betracht ziehen. Auf diese Weise können Sie die Implementierung der Basis verwenden, ohne eine falsche IS-A-Beziehung in die Welt zu setzen.

3voto

Sergey Galin Punkte 386

Am besten ist es, die Konstruktoren der Klasse zu schützen. Auf diese Weise kann die Klasse nicht direkt instanziiert werden und ist daher im Wesentlichen abstrakt:

class SomeBaseClass 
{
protected:
    SomeBaseClass() {}
    SomeBaseClass(const SomeBaseClass &) {}
    SomeBaseClass &operator=(const SomeBaseClass&) {}
public:
    virtual ~SomeBaseClass() {}
    ...
};

Oder, neuerer Stil:

class SomeBaseClass 
{
protected:
    SomeBaseClass() = default;
    SomeBaseClass(const SomeBaseClass &) = delete;
    SomeBaseClass &operator=(const SomeBaseClass&) = delete;
public:
    virtual ~SomeBaseClass() = default;
    ...
};

Der Destruktor ist im Allgemeinen besser öffentlich zu halten, da man ein Objekt möglicherweise über seinen Basisklassenzeiger löschen möchte.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X