2010-12-09 44 views
1

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?

+1

Il y a un égaré() derrière un contraction de mon œil! ;) –

+0

@Fritschy: Oups. Merci! –

Répondre

2

Je pourrais trouver des programmes intelligents avec instanciation de modèle récursive, mais la réalité est que ce que vous avez fait est probablement plus simple que ce que je peux trouver. Il est rare que je suggère que l'état global est une idée intelligente, mais sur celui-ci je peux devoir accepter que je ne peux pas faire mieux.

+0

+1 pour prendre le temps de lire tout ce code :) –

+0

Eh bien, c'est du code propre avec des intentions propres :). La réponse de DeadMG est ce que j'aurais pu écrire. –

+0

Juste curieux ... à quoi pourrait ressembler un exemple utilisant la solution de modèle? –