Ich werde ein paar Optionen. Alle haben Vor- und Nachteile. Wenn es NICHT möglich ist, VisualizerObject
zu ändern, wie ich in Kommentaren bemerkte, könnte der Effekt durch Verwendung des Präprozessors erreicht werden, da der Präprozessor den Gültigkeitsbereich nicht respektiert und die Frage speziell die Lebensdauer eines Objekts auf eine Weise steuert das überschreitet Bereichsgrenzen.
#ifdef VISUALIZE_OUTPUT
VisualizerObject vis_object;
#endif
#ifdef VISUALIZE_OUTPUT
vis_object.initscene(objects_here);
#endif
Der Compiler wird jede Nutzung von vis_object
diagnostizieren, die nicht in #ifdef
/#endif
.
Die große Kritik ist natürlich, dass die Verwendung des Präprozessors als schlechte Übung in C++ gilt. Der Vorteil besteht darin, dass der Ansatz auch dann verwendet werden kann, wenn es nicht möglich ist, die VisualizerObject
-Klasse zu modifizieren (z. B. weil sie in einer Bibliothek eines Drittanbieters ohne bereitgestellten Quellcode ist).
Dies ist jedoch die einzige Option, die das vom OP angeforderte Feature der Objektlebensdauer über Bereichsgrenzen hinweg anfordert.
Wenn es möglich ist, die VisualizerObject
Klasse zu ändern, macht es zu einem Vorlage mit zwei Spezialisierungen
template<bool visualise> struct VisualizerObject
{
// implement all member functions required to do nothing and have no members
VisualizerObject() {};
void initscene(types_here) {};
};
template<> struct VisualizerObject<true> // heavyweight implementation with lots of members
{
VisualizerObject(): heavy1(), heavy2() {};
void initscene(types_here) { expensive_operations_here();};
HeavyWeight1 heavy1;
HeavyWeight2 heavy2;
};
int main()
{
VisualizerObject<VISUALIZE_OUTPUT> vis_object;
...
vis_object.initscene(objects_here);
...
vis_object.drawScene(objects_here);
}
Die oben wird in allen C++ Versionen arbeiten. Im Wesentlichen funktioniert es entweder durch Instantiierung eines Lightweight-Objekts mit Member-Funktionen, die nichts tun, oder Instanziierung der Schwergewichtsversion.
Es wäre auch möglich, den obigen Ansatz zu verwenden, um eine VisualizerObject
zu wickeln.
template<bool visualise> VisualizerWrapper
{
// implement all required member functions to do nothing
// don't supply any members either
}
template<> VisualizerWrapper<true>
{
VisualizerWrapper() : object() {};
// implement all member functions as forwarders
void initscene(types_here) { object.initscene(types_here);};
VisualizerObject object;
}
int main()
{
VisualizerWrapper<VISUALIZE_OUTPUT> vis_object;
...
vis_object.initscene(objects_here);
...
vis_object.drawScene(objects_here);
}
Der Nachteil von beiden der Vorlage Ansätze ist Wartung - wenn eine Elementfunktion einer Klasse (Template-Spezialisierung) Zugabe ist es notwendig, eine Funktion mit der gleichen Signatur auf den anderen hinzuzufügen. In großen Teameinstellungen ist es wahrscheinlich, dass das Testen/Erstellen meistens mit einer Einstellung von VISUALIZE_OUTPUT
oder der anderen erfolgt - so ist es leicht, eine Version aus der Ausrichtung (unterschiedliche Schnittstelle) zu der anderen zu bekommen. Probleme (z. B. ein fehlgeschlagener Build beim Ändern der Einstellung) treten wahrscheinlich zu ungünstigen Zeitpunkten auf - zum Beispiel dann, wenn eine enge Frist für die Lieferung einer anderen Version des Produkts besteht.
Pedantisch ist der andere Nachteil der Vorlage Optionen, dass sie mit der gewünschten „Art von Muster“, das heißt die if
in
if(VISUALIZE_OUTPUT)
{
vis_object.initscene(objects_here);
}
und Objektlebensdauern nicht nicht kreuzen Umfang Grenzen erforderlich nicht entsprechen .
Haben Sie ** ein Leistungsproblem gemessen, wenn Sie nur 'VisualizerObject vis_object;' im äußersten Bereich haben, der es sein muss? – Caleth
Ich denke, Ihre gewünschte "Art von Muster" ist fehlerhaft - im Wesentlichen suchen Sie eine Möglichkeit, Dinge in einer Weise zu tun, die den Umfang nicht respektiert. Daher wäre eine praktikable Option, 'VISUALIZE_OUTPUT' zu einem Präprozessor-Makro zu machen und sowohl die Definition als auch die Verwendung von' vis_object' in '#ifdef VISUALISE_OUTPUT' /' # endif' zu verpacken. Dies funktioniert, da der Präprozessor den Gültigkeitsbereich nicht berücksichtigt. Bedenken Sie jedoch, dass die Verwendung von Preprozessor-Tricks in C++ aus guten Gründen dringend vermieden wird. – Peter