2011-04-21 2 views
0

Je fais une Random classe simple:Utilisation d'une classe aléatoire d'une manière statique

class Random 
{ 
public: 
    static bool seeded = false; 

    static void SeedRandom(int number) 
    { 
     srand(number); 
    } 
    static int GetRandom(int low, int high) 
    { 
     if (!seeded) 
     { 
      srand ((int)time(NULL)); 
     } 
     return (rand() % (high - low)) + low; 
    } 
}; 

Il est évident que C++ ne permet pas une classe entière à être déclarée comme static (qui est ce qui rend ce si facile en C#). J'ai plutôt fait tous les membres comme static. Il n'y a pas non plus de constructeur static donc je n'ai aucun moyen d'initialiser mon bool seeded sauf si j'appelle une fonction à la main, ce qui va à l'encontre du but. Je peux utiliser un constructeur normal dans lequel je devrais créer une instance de Random, ce que je ne veux pas faire.

Est-ce que quelqu'un sait si le nouveau standard C++ 0x autorisera des classes statiques et/ou des constructeurs statiques?

+0

Le bit 'bool seeded = false' de votre classe n'est pas valide. Seuls les membres intergal ** const ** statiques peuvent être initialisés dans le corps d'une classe de cette façon. Vous devez déclarer 'seeded' séparément et l'initialiser au point de déclaration (plutôt qu'au point de définition). –

Répondre

6

C++ ne permet pas de déclarer une classe comme statique

Bien sûr, il le fait. Vraiment, il n'y a aucune raison de mettre cela dans une classe. C++ ne vous force pas à tout mettre en classe - pour de bonnes raisons. En C# vous êtes obligé de tout mettre dans une classe et de déclarer les choses dans des méthodes statiques et autres, mais qui n'est pas idéomatique C++.

Vous ne pouvez vraiment pas simplement prendre le code C# idéomatique, et écrivez cela en C++, et attendez-vous à ce qu'il fonctionne bien. Ce sont des langages très différents avec des exigences et des caractéristiques de programmation très différentes.

Si vous voulez une méthode C++ idéomatique, ne créez pas de classe du tout. Appelez srand l'intérieur de votre main et définir une fonction qui fait votre serrage:

int RandomInteger(int high, int low) 
{ 
    return (std::rand() % (high - low)) + low; 
} 

EDIT: Bien sûr, il serait préférable pour vous d'utiliser la nouvelle installation de génération de nombres aléatoires et uniform_int_distribution pour obtenir votre gamme pincé au lieu de rand. Voir rand() considered harmful.

+0

Dire que la variable aléatoire a un stockage statique n'est pas tout à fait exact pour C++. Comme il est défini ci-dessus, il s'agit d'une variable globale (qui est probablement ce qui est requis). Une variable statique aurait une portée locale dans le module dans lequel elle a été définie. – Blazes

+2

@Blazes: Les variables globales ont une durée de stockage statique en C++. C++ définit 3 durées de stockage (bien, la durée de stockage 'thread' a été ajoutée en C++ 11):' automatic' (variables "stack allouées"), 'static' (variables globales et variables' static' locales), et ' dynamic' (alloué avec 'malloc' ou' new'). Les variables automatiques vivent jusqu'à la fin de leur bloc, les variables dynamiques restent actives jusqu'à ce que 'delete' ou' free' soit appelé, et les variables statiques restent actives jusqu'à la fin du programme. –

+1

@Blazes: Pour être clair, la durée de stockage statique n'a rien à voir avec le mot clé static. (Il est détaillé dans la section 3.7 dans ma copie de la norme ...) –

2

Votre static bool seeded devra de toute façon être défini dans un fichier cpp, et vous devrez l'initialiser là.

bool Random::seeded = false; 
0

Essayez ceci:

class Random 
{ 
public: 
    static bool seeded; 

    static void SeedRandom(int number) 
    { 
     srand(number); 
     seeded = true; 
    } 

    static int GetRandom(int low, int high) 
    { 
     if (!seeded) 
      SeedRandom(time(0)); 
     return (rand() % (high - low)) + low; 
    } 
}; 

bool Random::seeded; 

staticbool s initialisés à false par défaut, donc pas besoin de le faire explicitement. Notez que la logique de votre classe était également erronée, car vous n'avez jamais défini seeded sur true.

+0

Ceci est une bonne classe, mais vous avez tort à propos de Random :: seeded étant initialisé à 'false' par défaut. En mode débogage, il sera défini sur 'false', mais en version, il aura une valeur aléatoire sauf s'il est spécifiquement initialisé. Toujours initialiser les variables membres. – Blazes

+2

@Blazes: 'seeded' n'est pas une variable membre, elle est' static'. De la norme C++ 03, §9.4.2/7: "* Les membres de données statiques sont initialisés et détruits exactement comme les objets non-locaux (3.6.2, 3.6.3)." Du §3.6.2/1: "* Les objets ayant une durée de stockage statique (3.7.1) doivent être initialisés à zéro (8.5) avant toute autre initialisation . *" Ainsi, 'seeded' sera ** toujours ** zéro-initialisé, ce qui signifie bien sûr «faux» pour 'bool' - le standard l'impose. – ildjarn

+1

Pourquoi en faire une classe et non un espace de noms quand tout est public et statique? Parfois, la réponse à "Comment puis-je faire cela?" est "Ne fais pas ça!". ("Docteur, docteur - ça fait mal quand je fais ça!"). –

0

Vous pouvez toujours approcher ceci avec un motif singleton, en ayant le constructeur privé et un accesseur statique pour l'objet.


class Random 
{ 
public: 
    static Random& instance() 
    { 
    static Random instance; 

    return instance; 
    } 

    // your other functions here 

private: 
    Random() 
    { 
    // your seed code here 
    }  
}; 

Cela vous permettra de n'avoir une seule instance de la classe et chaque fois que vous avez besoin d'une fonction aléatoire, vous avez juste besoin d'appeler l'instance de Random().()

+2

Ne vois pas beaucoup de raisons de créer un singleton (votre classe Random) pour un autre singleton (std :: rand/std :: srand). –

+0

La même logique peut être appliquée pour expliquer pourquoi utiliser une autre classe, elle fournit simplement un wrapper d'accès global à instance unique, qui peut être étendu avec toutes les fonctionnalités dont l'utilisateur a besoin. –

+0

Et je dirais que l'on ne devrait pas utiliser une autre classe ici. C++ n'exige pas que tout soit dans une classe. La programmation de cette manière n'utilise pas la langue de manière efficace. –

0

Quelle est la raison pour vous avoir une classe avec des méthodes statiques?Peut être qu'il existe un remplaçant pour atteindre votre objectif. Cherchez-vous quelque chose de similaire à singleton? BTW si vous avez des variables membres statiques dans votre déclaration de classe, comme indiqué par d'autres réponses avant moi, vous devez les initialiser en dehors de la classe (de préférence dans le fichier cpp) avant de les utiliser. Donc, si vous suivez ceci et initialisez votre comme ceci:

bool Random::seeded = false
il sera automatiquement initialisé à false comme vous voulez.

1

Vous n'avez pas besoin de tout faire une classe en C++.

namespace Random 
{ 
    bool seeded = false; 

    void SeedRandom(int number) 
    { srand(number); } 

    int GetRandom(int low, int high) 
    {   
     if (!seeded) 
     { srand((int)time(NULL)); } 

     return (rand() % (high - low)) + low; 
    }  

} 
Questions connexes