Ich habe eine Hierarchie von Operationen und (geteilten) Informationsklassen, in denen intuitiv scheint es keine Notwendigkeit für Laufzeitpolymorphismus, und doch kann ich keine Lösung ohne es finden.CRTP mit einer zyklischen Abhängigkeit
Für diese Frage angenommen, es gibt eine 2-Level-Hierarchie. Es gibt eine Basisoperation und eine abgeleitete Operation. Objekte auf derselben Hierarchiestufe müssen möglicherweise Informationen zwischen ihnen austauschen (dh, dass Basisoperationsobjekte Basisinformationen gemeinsam nutzen müssen und abgeleitete Operationsobjekte abgeleitete Informationen gemeinsam nutzen müssen, Basisoperationsobjekte jedoch niemals abgeleitete Informationen oder Laster gemeinsam nutzen müssen versa).
So beginnt es wie folgt aus:
// Shared between base operation objects
class base_info
{
};
// Shared between derived operation objects
class derived_info :
public base_info
{
};
Da gibt es keine Laufzeit-Frage, über die Operation Anteil Objekte, die Informationsobjekte, gibt es auch die folgende ist:
template<class Info>
class base_op
{
std::shared_ptr<Info> m_info;
};
class derived_op :
public base_op<derived_info>
{
};
Der Rest der Code instanziiert immer base_op
mit base_information
, und so ist hier kein Laufzeitpolymorphismus erforderlich.
Jetzt können die gemeinsam genutzten Informationsobjekte an einigen Punkten entscheiden, dass sie neue Operationen generieren müssen. Wie oben gesehen, benötigen Operationsobjekte gemeinsam benutzte Zeiger auf geteilte Informationsobjekte. So ist die Informationshierarchie wechselt:
// Shared between base operation objects
class base_info :
private std::enable_shared_from_this<base_info>
{
void do_something_spawning_new_ops();
};
...
Das Problem ist nun, wie do_something_spawning_new_ops
zu implementieren. Mit Laufzeit polymporphism, dann ist es nicht so schwierig:
class base_info :
private std::enable_shared_from_this<base_info>
{
void do_something_spawning_new_ops()
{
// Need a new op.
get_op_shared_ptr();
}
virtual std::shared_ptr<base_op> get_op_shared_ptr()
{
// use shared_from_this, create a base_op object using it.
}
};
class derived_info :
public base_info
{
virtual std::shared_ptr<base_op> get_op_shared_ptr()
{
// use shared_from_this + std::*_pointer_cast,
// create a derived_op object
}
};
aber der Punkt ist Runtime Polymorphismus zu vermeiden, da durch Design, alles kann bei der Instanziierung bekannt sein. So zu Beginn des Posts zurück, wäre es so etwas wie dies schön gewesen sein zu haben:
template<class Op>
class base_info
{
};
class derived_info :
public base_info<derived_op>
{
};
mit CRTP Art von Dingen (wenn auch ohne die Ableitung), wo die op sagt, dass es eine Info hält die Schaffung Objekte dieses Typs. Dies verursacht nun jedoch ein zyklisches Problem für die Instanziierung von base_op
. Es muss irgendwie durch irgendeinen Informationstyp instanziiert werden, der selbst durch seinen eigenen Typ instanziiert wird, usw. usw. Ich weiß nicht, wie man diesen Typzyklus abbremst.
bearbeiten
Nach Panta rhei Anregung here ist der Code, den ich für Ziel bin.
CRTP beinhaltet Downcasting von Base zu abgeleitet. Ich sehe das nirgendwo hier. Geben Sie ein vollständiges, aber minimales Beispiel für Code an, der das Problem veranschaulicht. –
Zyklische Abhängigkeiten können durch Verzögerung der Template-Instanziierung gelöst werden. Dies kann durch Hinzufügen einer weiteren Ebene erfolgen. – rpress
Sie haben eine Menge unbekannter/vager Sachen in Ihrer Frage hinterlassen. Bitte geben Sie einen [MCVE] (http://stackoverflow.com/help/mcve) an oder zumindest einen Link zu einem, z. mit einer Online-IDE wie [Ideone] (http://ideone.com/). –