2016-07-30 24 views
1

Ich versuche eine komplizierte Klasse zu implementieren, deren Konstruktion die Spezifikation einer Bedingung erfordert, die es dem Konstruktor ermöglicht, zu bestimmen, wann das Objekt konstruiert wurde. Betrachten wir zum Beispiel:Lose Klassenkopplung und Datenzugriff

class RigidBody 
{ 
    private: 
     std::vector<double> trajectory_; 
     // Other stuff... 
    public: 
     RigidBody(std::unique_ptr<TerminateCondition>, std::vector<double> const &); 
     // Other stuff... 
}; 

Hier ist, was der Konstruktor könnte wie folgt aussehen:

RigidBody::RigidBody(std::unique_ptr<TerminateCondition> condition, std::vector<double> const &p) 
{ 
    int n = 0; 
    while(!condition->Done(/* Signature */)) 
    { n++; 
     /* Do other stuff... */ 
     // such as, trajectory_.push_back(sin(n * dt)); 
    } 
} 

ich TerminateCondition vorstellen, eine abstrakte Klasse zu sein.

Nachfrage 1: Der Zugang zu RigidBody Mitglieder

ich class TerminateConditionAtRest: public TerminateCondition möchte der Lage sein, trajectory_ zu verwenden, so dass ich auf Bedingungen wie std::abs(trajectory.back() - trajectory_[0]) < epsilon beenden könnte. Müsste ich Done(...) zwingen, ein vector const & als ein Eingabeargument zu nehmen und trajectory_ an es zu übergeben?

Nachfrage 2: Flexibilität mit Unterschrift von Done(...)

I class TerminateConditionNumSteps: public TerminateCondition zu Flagge Done wenn n > 1000 oder etwas Ähnliches wollen könnte. Grundsätzlich könnte ich etwas Flexibilität mit der /* Signature */ drin nutzen.

Wie erreiche ich eine solche Einrichtung, bei TerminateCondition->Done kann wie n Verwendung von so unterschiedlichen einer Reihe von Variablen zur Verfügung im Rahmen des RigidBody Konstruktor, wie private Mitglieder wie trajectory_ oder Einheimischen machen?

Ich bin nur auf der Suche nach ultimative Flexibilität bei der Modellierung der Schleife Abbruchbedingung. Es scheint nicht so, als ob eine abstrakte Klasse erlaubt, flexibel mit der Eingabeargumentsignatur zu sein. Auf der anderen Seite scheint eine abstrakte Klasse das einzige zu sein, was es mir erlauben würde, die Bedingung zur Laufzeit zu spezifizieren.

Danke.

+1

Zu 1: Du könntest alternativ ein Factory-Objekt übergeben, das die richtige Bedingung im 'RigidBody'-C'tor von' this' erzeugt, dh. mit vollem 'RigidBody'-Zugriff (das heißt" öffentlich "). – m8mble

+1

Betreffend 2: Unter Verwendung einer abstrakten Grundbedingung wird grundsätzlich gesagt: "Ob wir fertig sind, wird anhand der folgenden Signatur ermittelt". Wenn Sie das nicht wollen, brauchen Sie vielleicht etwas wie eine Flugbahnfabrik, die automatisch entscheidet, ob es getan ist. – m8mble

+1

Und schließlich im Allgemeinen: Es scheint, als ob Sie eine Schnittstelle ('RigidBody') haben, deren Aufbau Sie trennen/modularisieren möchten. Warum nicht genau das tun? Genauer gesagt: Fügen Sie die Klasse 'RigidBodyConstructionInfo' hinzu, auf deren Grundlage ein' RigidBody' konstruiert werden kann. Die 'RigidBodyConstructionInfo' wiederum kann aus einer Factory-Schnittstelle erstellt werden, deren Implementierung von der Laufzeit abhängt. – m8mble

Antwort

1

Es ist nur mein Gedanke. Vielleicht wollen Sie so etwas benutzen ?:

class TrajectoryCreator 
{ 
public: 
    virtual vector<float> create(const vector<float>& path) = 0; 
} 

Dann können Sie bestimmte Flugbahn erstellen Sie wollen:

RigidBody(TrajectoryCreator& t, const vector<float> &p) 
    : trajectory_(t.create(p)) 
{} 

Leitgedanke dieser Lösung ist, bewegen Logik der Schaffung Bahn in separaten Klasse