Je travaille encore sur mon hybride fermé/open source mentionné plus tôt dans this question. L'application en question est en fait une application comme busybox - il y a plusieurs programmes regroupés dans un seul programme, et l'exécution réelle du programme est choisie en fonction de la première commande entrée. Cela permet aux sous-programmes de partager une copie du CRT (je ne peux pas utiliser le redist installable car j'ai besoin de maintenir un déploiement binaire unique), ainsi que plusieurs internes utiles dans plusieurs sous-programmes. Parce que certains des sous-programmes eux-mêmes ne peuvent pas être libérés en raison de restrictions de licence, je considère utiliser un démarrage comme celui-ci. (Désolé pour la quantité de code :()Cette utilisation de l'initialisation statique globale est-elle acceptable pour une application de style "busybox"?
ISubProgram.hpp
#include <string>
struct ISubProgram
{
virtual std::wstring GetExecutive() const = 0; //Return sub program name
virtual void OnStart(int argc, const char *argv[]) {};
virtual int Run(int argc, const char *argv[]) = 0;
virtual ~ISubProgram() {}
};
SubProgramList.hpp
#include <memory>
#include <boost/ptr_container/ptr_map.hpp>
#include <boost/noncopyable.hpp>
#include "ISubProgram.hpp"
class SubProgramList;
SubProgramList& GetSubProgramList();
class SubProgramList : boost::noncopyable
{
friend SubProgramList& GetSubProgramList();
SubProgramList() {} //Disallow direct creation.
boost::ptr_map<std::wstring,ISubProgram> programs;
public:
void RegisterProgram(std::auto_ptr<ISubProgram> subProgramToRegister);
ISubProgram * FindProgramFromExecutive(const std::wstring& executive);
void CallOnStartMethods(int argc, char *argv[]);
};
template <typename T>
struct RegisterSubProgram
{
RegisterSubProgram()
{
std::auto_ptr<ISubProgram> toAdd(new T);
GetSubProgramList().RegisterProgram(toAdd);
}
}
SubProgramList.cpp
SubProgramList& GetSubProgramList()
{
static SubProgramList theList;
return theList;
}
//Implementations of the class methods
ExampleSubProgram.cpp
#include "SubProgramList.hpp"
struct ExampleSubProgram : public ISubProgram
{
virtual std::wstring GetExecutive()
{
return L"ExampleSubProgram";
}
virtual int Run(int argc, const char *argv[])
{
//Run this program :)
}
};
namespace { RegisterSubProgram<ExampleSubProgram> registrar; }
Main.cpp
#include "SubProgramList.hpp"
int main(int argc, char *argv[])
{
SubProgramList& list = GetSubProgramList();
list.CallOnStartMethods(argc, argv);
std::wstring subProgramName(/*.. Generate from argv[1] ...*/);
FindProgramFromExecutive(subProgramName)->Run(argc, argv);
}
Je pense Je suis clair des questions d'ordre d'initialisation parce que le seul état global est une statique locale plutôt que statique globale. La raison principale de ceci est que je peux complètement séparer les bits de source fermée et de source ouverte du programme, ce qui rendrait la fusion rapide et efficace, et enlèverait aussi la plaque de mon "sélecteur de sous-programme Giant if/else actuel". "dans main
.
Est-ce une utilisation raisonnable de l'initialisation à l'initialisation (qui est généralement déconseillée?) Sinon, quelle autre implémentation suggéreriez-vous?
Il y a un égaré() derrière un contraction de mon œil! ;) –
@Fritschy: Oups. Merci! –