Frage

Ich habe eine Basisklasse mit einer optionalen virtuellen Funktion

class Base {
    virtual void OnlyImplementThisSometimes(int x) {}
};

Als ich das kompilieren bekomme ich eine Warnung über die nicht verwendeten param x. Gibt es irgendeine andere Weise, die ich die virtuelle Funktion implementiert haben sollte? Ich habe es wie folgt neu geschrieben:

class Base {
    virtual void OnlyImplementThisSometimes(int x) 
    {
        x = 0;
    }
};

Ich habe auch das Problem, dass, wenn ich nicht aufpasse, die Unterklasse kann ich die falsche Funktion machen implementieren und dann merke ich, nicht wegen Überlastung. Z

class Derived : public Base {
    void OnlyImplementThisSometimes(int x, int y) { // some code }
};

Derived d;
Base *b = dynamic_cast<Base *>(&d);
b->OnlyImplementThisSometimes(x); // calls the method in the base class

Die Methode der Basisklasse genannt wurde, weil ich die abgeleitete Funktion mit einem „int y“ param implementiert, aber es gibt keine Warnung darüber. Sind diese nur häufige Fehler in C ++ oder habe ich virtuelle Funktionen falsch verstanden?

War es hilfreich?

Lösung

, um die Design-Probleme zu ignorieren Sie rund um die Compiler-Warnung über eine nicht verwendete Variable durch Weglassen der Variablennamen, zum Beispiel bekommen:

virtual void OnlyImplementThisSometimes(int ) { }

Irrtümlicherweise die falsche Methode Signatur Implementierung, wenn die virtuelle Funktion außer Kraft zu setzen versucht, ist nur etwas, das Sie vorsichtig in C sein müssen ++. Sprachen wie C # erhalten, um diesen mit dem ‚Überschreibung‘ Schlüsselwort.

Andere Tipps

Wir definieren einen Makro _unused wie:

#define _unused(x) ((void)x)

definieren Sie dann die Funktion als:

virtual void OnlyImplementThisSometimes(int x) { _unused( x );}

Dies hält nicht nur die Compiler beschweren, sondern macht es jedem klar den Code beibehalten, die Sie über x nicht vergessen haben -. Sie sind absichtlich ignoriert es

Warum es in der Basisklasse definieren? Wenn die Basisklasse nicht die Methode nicht benutzen will, dann nur definiert es als eine virtuelle Methode in der abgeleiteten Klasse.

oder die Default-Implementierung könnte eine Ausnahme auslösen

Wenn Sie eine Standardimplementierung einer virtuellen Funktion zur Verfügung stellen, sollte es eine richtige Implementierung für alle abgeleiteten Klassen, die diese Funktion nicht außer Kraft setzen. Wenn Sie nicht ein richtig Implementierung zur Verfügung stellen, dann wäre mein Rat eine rein virtuelle Funktion zu machen und es zu der abgeleiteten Klasse zu verlassen, um eine Implementierung zur Verfügung stellen. Abgeleitete Klassen, dass das Verfahren nicht zulassen aufgerufen werden kann, eine Ausnahme auslösen, um sicherzustellen, dass sie nicht versehentlich verwendet wird.

Neben einfach den Variablennamen verzichtet, wobei in vielen Compilern Sie den Compiler kann sagen, dass Sie sich bewusst sind, dass es nicht verwendet und SHUTUP ist dies, indem Sie

int func(int x)
{
   (void) x;
}

Das ist etwas gemeinsam in meinem Code. Zum Beispiel habe ich Klassen, die für Single-Threaded-Betrieb und Multi-Threading ausgelegt sind. Es gibt eine Menge von gemeinsamen Routinen und Daten. Ich habe das alles in der Basisklasse (die ein paar rein virtuelle hat auch).

ich implementieren zwei leere virtuelle Funktionen in der Basisklasse: Init () und Cleanup (). Die einzelnen Gewinde abgeleitete Klasse ist sie nicht impliment, aber die Mulit-threaded man tut.

Ich habe eine Fabrik-Funktion die approprite erstellen abgeleiteten Klasse dann einen Zeiger zurück. Der Client-Code kennt nur über die Basisklasse Typ und es ruft Init () und Cleanup (). Beide Szenarien das Richtige zu tun.

Natürlich kann es auch andere gute Vorschläge sein, wie dies zu tun, aber dieses Idiom funktioniert gut für viele meinen Code.

Es ist keine schlechte Praxis und es ist ein gemeinsames Idiom für Teile einer Klasse angeben, die optional zu implementieren ist.

Zur Zeit verwende ich es für ein Benutzer-Eingabesystem, weil es für einen Benutzer dieser Klasse sehr mühsam sein würde jede einzelne Methode zu implementieren sogar er höchstwahrscheinlich es sowieso nicht verwendet wird.

class mouse_listener{
public:
    virtual ~mouse_listener() {}

    virtual void button_down(mouse_button a_Button) {}
    virtual void button_up(mouse_button a_Button) {}
    virtual void scroll_wheel(mouse_scroll a_Scroll) {}
    virtual void mouse_move_abs(math::point a_Position) {}
    virtual void mouse_move_rel(math::point a_Position) {}
};

Btw, wenn Sie Ihre Basisklasse kennen, gibt es niemals eine Notwendigkeit dynamischen bis -casts zu tun, das heißt von der Basis abgeleitet.

Base *b = &d;

Wird genauso gut tun, dynamic_cast<> sollte stattdessen verwendet werden, wenn Sie nach unten Guss, das heißt von der Basis abgeleitet:

if((Derived *d = dynamic_cast<Derived *>(b)) != 0)
{
  // use d
}

(Und natürlich im Fall von unten Guss, static_cast<> wird in der Regel als gut.)

Versuchen Sie folgendes:

class Base {
    virtual void OnlyImplementThisSometimes(int x) = 0;
};

Es ist schon eine Weile her, seit ich Sachen wie das getan habe, aber ich glaube, das ist, wie Sie eine virtuelle Funktion deklarieren.

Auch wie andere gesagt haben, sind Variablennamen optional in Funktionsdeklarationen wie diese.

Die einfachste Antwort auf diese Frage ist wie folgt:

class Base {
    virtual void OnlyImplementThisSometimes(int x) { x;}
};

Ein einfacher Verweis auf die Variable, die nichts ist absolut alle Warnungen entfernen (von VC ++ auf höchstem Niveau sowieso).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top