2016-07-30 8 views
1

J'essaie d'implémenter une classe compliquée dont la construction nécessite la spécification d'une condition qui permet au constructeur de déterminer quand l'objet a été construit. Prenons, par exemple:Couplage de classes lâches et accès aux données

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

Voici ce que le constructeur pourrait ressembler à:

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)); 
    } 
} 

J'imagine TerminateCondition être une classe abstraite.

demande 1: Accès aux membres RigidBody

Je voudrais class TerminateConditionAtRest: public TerminateCondition pouvoir utiliser trajectory_, pour que je puisse mettre fin à des conditions telles que std::abs(trajectory.back() - trajectory_[0]) < epsilon. Aurais-je besoin de forcer Done(...) à prendre un vector const & en tant qu'argument d'entrée et lui transmettre trajectory_?

demande 2: flexibilité avec la signature de Done(...)

je pourrais vouloir class TerminateConditionNumSteps: public TerminateCondition pour marquer Done quand n > 1000 ou quelque chose de similaire. Fondamentalement, je pourrais utiliser une certaine flexibilité avec le /* Signature */ là-bas.

Comment puis-je obtenir une telle configuration, dans laquelle TerminateCondition->Done peut utiliser aussi divers un ensemble de variables disponibles dans le cadre du constructeur RigidBody, tels que les membres privés comme trajectory_ ou locaux comme n? Je cherche juste la flexibilité ultime dans la modélisation de la condition de terminaison de boucle. Il ne semble pas qu'une classe abstraite permette d'être flexible avec la signature d'argument en entrée. D'un autre côté, une classe abstraite semble être la seule chose qui me permettrait de spécifier la condition à l'exécution.

Merci.

+1

Concernant 1: Vous pouvez alternativement passer un objet d'usine, cela créera la condition correcte dans le c'tor 'RigidBody' de 'this'. avoir l'accès 'RigidBody' complet (le' public' qui est). – m8mble

+1

Concernant 2: L'utilisation d'une condition de base abstraite dit essentiellement: "Que nous ayons terminé, nous le déterminerons en fonction de la signature suivante". Si vous ne le voulez pas, vous avez peut-être besoin de quelque chose comme une usine de trajectoires, qui décide automatiquement si c'est fait. – m8mble

+1

Et enfin en général: Il semble que vous ayez une interface ('RigidBody') dont vous ne voulez pas séparer la construction/modulariser. Pourquoi ne pas faire exactement cela? Précisément: Ajoutez une classe 'RigidBodyConstructionInfo' basée sur laquelle un' RigidBody' peut être construit. Le 'RigidBodyConstructionInfo' à son tour peut être construit à partir d'une interface d'usine dont l'implémentation utilisée peut dépendre de choses d'exécution. – m8mble

Répondre

1

C'est juste ma pensée. Peut-être que vous voulez utiliser quelque chose comme ça ?:

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

Ensuite, vous pouvez créer la trajectoire spécifique que vous voulez:

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

L'idée principale de cette solution est logique de mouvement de la création de la trajectoire dans la classe séparée