2010-08-31 4 views
7

Ich erweitere eine Klasse von einer dritten Teilbibliothek zur Verfügung gestellt. Die Klasse, nennen wir sie Foo, hat eine reset() Methode, die aufgerufen werden kann, um das Verhalten von Foo neu zu starten. Die Methode reset() wird auch intern von der Klasse verwendet.Erzwingen Methoden Dritter Virtualität

class Foo 
{ 
    public: 
    void reset() { 
     /* ... */ 
    } 
    void something() { 
     reset(); 
    } 
}; 

Bisher muss ich die reset() Methode, um zu überlasten meine zusätzliche Funktionen wie auch zurück:

class Bar : public Foo 
{ 
    public: 
    void reset() { 
     /* ...something... */ 
     Foo::reset(); 
    } 
}; 

Leider, da die Foo::reset() Methode ist nicht virtuell, durch Bar::something() Aufruf ich das bekommen Foo::reset() Methode aufgerufen anstelle von Bar::reset().

Gibt es einen Weg (anders als das Überladen Foo::something()), um es rückwärts-virtuell zu machen?

+0

Übrigens habe ich auf diese Weise gelernt, jede Methode, die sowohl öffentlich als auch intern verwendet wird, als virtuell zu setzen. – Dacav

+1

Das ist eine schlechte Entscheidung, google für NVI und Sie werden einen Trend zur Vermeidung von öffentlichen virtuellen Methoden sehen. Das Problem, mit dem Sie konfrontiert sind, ist anders: Sie können keine Klasse erweitern, die nicht erweitert wurde. –

+0

Ich unterstütze stark Non Virtual Interfaces. Die Verwendung von 'virtuellen' öffentlichen Methoden ähnelt der Rückgabe von Handles an Ihre Interna -> es ist ein Nein-Nein. –

Antwort

5

Sie können keine Klassen erweitern, die nicht erweitert werden sollten.

1

Nein, das ist nicht möglich. Die Virtualität einer Methode wird bei der Deklaration der Methode festgelegt und kann später in einer Basisklasse nicht mehr geändert werden.

Um dies zu ermöglichen, wäre nichts weniger als eine Katastrophe. Virtuelle Methoden verhalten sich einfach anders als nicht-virtuelle Methoden und müssen beim Entwerfen eines Objekts berücksichtigt werden. Mit diesem Vorschlag müsste ich berücksichtigen, dass sich alle meine Methoden auf zwei deutlich unterschiedliche Arten verhalten können. Dies trägt wesentlich zu den Designkosten der Anwendung bei und verringert die Zuverlässigkeit.

1

Wenn weder Reset noch etwas virtuell sind, bist du verrückt, und das ist das Ende der Geschichte. Wenn etwas virtuell ist, könnten Sie es überschreiben. Wenn diese erforderlichen Methoden jedoch nicht virtuell sind, ist die Klasse nicht dazu gedacht, erweitert zu werden (oder wenn sie richtig implementiert wurde, falls dies beabsichtigt war).

Edit:

Sie könnten versuchen Zusammensetzung, z.B.

Aber wenn Sie die ganze, implizite Konvertierung, Ding brauchen, sind Sie immer noch gefüllt.

3

Sie können reset() virtuell in Ihrer Bibliothek nicht so machen, dass es sich auf die Basisklasse auswirkt, ohne den Code der Basisklasse zu ändern. Für den Anfang hat der Compiler nicht den notwendigen Buchhaltungscode hinzugefügt, der es ermöglicht, virtuelle Aufrufe an reset() zu tätigen.

2

Es gibt keinen "sauberen Weg", es mit Vererbung zu machen. Virtual ist ein Kompilierungs/Link-Zeitunterschied: Verwenden einer Vtable zum Auflösen der Methode zur Laufzeit (virtuell) vs. direkte Verknüpfung (nicht virtuell).

Verwandte Themen