7 Stimmen

Erzwingen von korrekten Parametertypen in abgeleiteten virtuellen Funktionen

Es fällt mir schwer, dieses Problem kurz zu beschreiben, daher habe ich den Code für ein Demonstrationsprogramm beigefügt.

Die allgemeine Idee ist, dass wir eine Reihe von abgeleiteten Klassen wollen, die gezwungen sind, eine abstrakte Foo()-Funktion von einer Basisklasse zu implementieren. Jeder der abgeleiteten Foo()-Aufrufe muss einen anderen Parameter als Eingabe akzeptieren, aber alle Parameter sollten ebenfalls von einer BaseInput-Klasse abgeleitet sein.

Wir sehen bisher zwei mögliche Lösungen, mit denen wir nicht sehr zufrieden sind:

  1. Entfernen Sie die Funktion Foo() aus der Basisklasse und implementieren Sie sie mit den richtigen Eingabetypen in jeder abgeleiteten Klasse neu. Damit entfällt jedoch die Anforderung, dass die Funktion in jeder abgeleiteten Klasse auf die gleiche Weise implementiert werden muss.

  2. Führen Sie eine Art dynamischen Cast innerhalb der empfangenden Funktion durch, um zu überprüfen, ob der empfangene Typ korrekt ist. Dies hindert den Programmierer jedoch nicht daran, einen Fehler zu machen und den falschen Eingabedatentyp zu übergeben. Wir möchten, dass der Typ, der an die Funktion Foo() übergeben wird, zur Kompilierzeit korrekt ist.

Gibt es eine Art Muster, das ein solches Verhalten erzwingen könnte? Verstößt diese ganze Idee gegen eine grundlegende Idee, die der OOP zugrunde liegt? Wir würden wirklich gerne Ihre Meinung zu möglichen Lösungen hören, die über das hinausgehen, was wir uns ausgedacht haben.

Vielen Dank!

#include <iostream>

// these inputs will be sent to our Foo function below
class BaseInput {};
class Derived1Input : public BaseInput { public: int   d1Custom; };
class Derived2Input : public BaseInput { public: float d2Custom; };

class Base
{
public:
    virtual void Foo(BaseInput& i) = 0;
};

class Derived1 : public Base
{
public:
    // we don't know what type the input is -- do we have to try to cast to what we want
    // and see if it works?
    virtual void Foo(BaseInput& i) { std::cout << "I don't want to cast this..." << std::endl; }

    // prefer something like this, but then it's not overriding the Base implementation
    //virtual void Foo(Derived1Input& i) { std::cout << "Derived1 did something with Derived1Input..." << std::endl; }
};

class Derived2 : public Base
{
public:
    // we don't know what type the input is -- do we have to try to cast to what we want
    // and see if it works?
    virtual void Foo(BaseInput& i) { std::cout << "I don't want to cast this..." << std::endl; }

    // prefer something like this, but then it's not overriding the Base implementation
    //virtual void Foo(Derived2Input& i) { std::cout << "Derived2 did something with Derived2Input..." << std::endl; }
};

int main()
{
    Derived1 d1; Derived1Input d1i;
    Derived2 d2; Derived2Input d2i;

    // set up some dummy data
    d1i.d1Custom = 1;
    d2i.d2Custom = 1.f;

    d1.Foo(d2i);    // this compiles, but is a mistake! how can we avoid this?
                    // Derived1::Foo() should only accept Derived1Input, but then
                    // we can't declare Foo() in the Base class.

    return 0;
}

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