c'est ma première question sur le débordement de la pile, alors soyez doux. Permettez-moi d'abord d'expliquer le comportement exact que je voudrais voir. Si vous êtes familier avec C#, vous savez que déclarer une variable comme "readonly" permet à un programmeur d'assigner une valeur à cette variable exactement une fois. D'autres tentatives de modification de la variable entraîneront une erreur. Ce que je suis en train de faire: Je veux m'assurer que toutes les classes d'une tonne que je définis peuvent être instanciées de manière prévisible exactement une fois dans mon programme (plus de détails en bas).Atteindre C# "readonly" comportement en C++
Mon approche de la réalisation de mon objectif est d'utiliser extern de déclarer une référence mondiale à la seule tonne (que je plus tard instancier à un moment que je choisis. Ce que je ressemble un peu comme cela,
namespace Global
{
extern Singleton& mainInstance; // not defined yet, but it will be later!
}
int main()
{
// now that the program has started, go ahead and create the singleton object
Singleton& Global::mainInstance = Singleton::GetInstance(); // invalid use of qualified name
Global::mainInstance = Singleton::GetInstance(); // doesn't work either :(
}
class Singleton
{
/* Some details ommited */
public:
Singleton& GetInstance()
{
static Singleton instance; // exists once for the whole program
return instance;
}
}
Toutefois, cela ne fonctionne pas vraiment, et je ne sais pas où aller d'ici
Quelques détails sur ce que je suis contre.
Je suis préoccupé par le filetage que je travaille code qui traitera de la logique du jeu pendant que communiquant avec plusieurs processus tiers et d'autres processus que je vais créer. Finalement, j'aurais pour implémenter une sorte de synchronisation afin que plusieurs threads puissent accéder aux informations dans la classe Singleton sans souci. Parce que je ne sais pas quels types d'optimisations je pourrais faire, ou exactement ce que le filetage implique (jamais fait un vrai projet en l'utilisant), je pensais que pouvoir contrôler de manière prévisible quand Singletons étaient instanciées serait un bon Chose. Imaginez si le processus A crée le processus B, où B contient plusieurs singletons répartis sur plusieurs fichiers et/ou bibliothèques. Cela pourrait être un vrai cauchemar si je ne peux pas assurer de façon fiable l'ordre dans lequel ces objets singleton sont instanciés (parce qu'ils peuvent dépendre l'un de l'autre, et appeler des méthodes sur un objet NULL est généralement une mauvaise chose).
Si j'étais en C#, j'utiliserais simplement le mot-clé readonly, mais est-il possible de mettre en œuvre ce comportement (compilé) en C++? Est-ce même une bonne idée? Merci pour vos commentaires.
Modifier
Si je fermai pour suivre l'exemple de code ci-dessus, la réponse choisie serait la meilleure façon de faire ce que je avais besoin. J'ai décidé de changer le modèle de singleton, même si je prévois de faire un de ces objets EntryPoint.
class EntryPoint
{
/* Intentionally defined this way to discourage creation */
EntryPoint(const EntryPoint &); // undefined & private
EntryPoint& operator=(const EntryPoint &); // undefined & private
// public
EntryPoint()
{
/* All of the action is performed here! */
}
/* Other supporting functions */
}
// The easier to understand main function!
int main()
{
EntryPoint * ep = new EntryPoint(); // transfer control to the entrypoint
delete ep;
}
L'une des raisons pour lesquelles je pensais que je aurais besoin de tous ces singletons est que je prévois de créer une architecture plus large qui soutiendrait les applications plug-in de type modulaire. Je voulais également plus de vérification des erreurs et de protection de la mémoire pour minimiser les fuites de mémoire. J'ai été heureux de constater que le Qt multiplateforme (http://qt.nokia.com/) offre un pointeur gardé et d'autres fonctionnalités intéressantes.
Il semble que 'const' devrait faire l'affaire. Mais non, je ne pense pas que ce soit une bonne idée. Les singletons sont assez mauvais dans leur incarnation "normale". Les rendre encore plus complexes ne fera que revenir et vous mordre. Pourquoi avez-vous tous ces singletons de toute façon? Le moyen le plus simple de contrôler l'ordre d'instanciation est d'arrêter de faire la moitié de vos variables static/globals/singletons – jalf