2010-02-09 7 views
4

J'ai quelques questions de base sur la conception/syntaxe C++ et j'apprécierais votre réponse.Utilisation d'une structure de données vectorielles - questions de conception et de syntaxe

  • Je N nombre de régions
  • Chaque région doit stocker des informations sur un objet « élément »

-à-dire que je veux réaliser quelque chose comme ceci:

region[i].elements = liste des tous les éléments pour la région i.

Question 1: La syntaxe suivante (voir le code ci-dessous)/conception semble correcte. Est-ce que je manque quelque chose ici?

EDIT

Les instances de élém struct sont créés par une autre classe et sa désaffectation mémoire est poignées par cette classe que je veux juste accéder à cet objet et de ses membres en utilisant reg [i] .elements list (vector) ... alors, comment dois-je ajouter ces objets élément au vecteur "elements" dans la classe Region?

// Déjà cette stucture que je dois utiliser

struct elemt { 
    int* vertex; 
    int foo1; 
    double foo2; 
}; 


class Region{ 
    public: 
     // I am not sure what should be the syntax here! 
     // is it correct? 
     std::vector <elemt*> elements;  
} 

// Following is the constructor of "class A" 
A::A(){ 
    // --header file defines: Region *reg; 
    // Let numOfRegions be a class variable. (changes based on "Mac"'s suggestion) 
    numOfRegions = 100; 
    //allocate memory: 
    reg = new Region[numOfRegions]; 
} 

A::~A(){ 
    delete [] reg; 
    reg = NULL; 
} 

A::doSomething(){ 

// here I want to append the elements to the vector 
// Let i be region 10. 
// Let e1 be an element of "struct elemt" that needs to be added 

    reg[i].elements.push_back(e1); 

} 

Question 2: Est-ce la syntaxe correcte doSomething()? Plus tard, je veux lancer un itérateur sur tous les éléments dans reg[i] et que vous voulez accéder, e1->foo1, e1->foo2 et comme ça.

Question 3: Vouz méthode de quelque chose, comment puis-je assurer que e1 est pas déjà dans les « éléments »

MISE À JOUR

Correction de quelques erreurs de syntaxe, et nous espérons que fixe fuite de mémoire remarqué par l'utilisateur 'Mac. '

+0

Où est la question 1? :-) –

+0

désolé je ne l'ai pas fait 'gras' .. le fera :-) Question 1: Est-ce que la syntaxe/conception suivante semble correcte. Est-ce que je manque quelque chose ici? – memC

+1

btw, pour la vérification de syntaxe, vous avez un gourou assis directement dans votre ordinateur: le compilateur! –

Répondre

5

Tout d'abord se débarrasser de la fuite de mémoire du code.

A::A(int numOfRegions = 100){ 

    m_reg = new Region[numOfRegions]; // define Region *m_reg in the class 
} 

A::~A(){ 
    delete [] m_reg; 
    m_reg = NULL; 
} 

You are allocating memory in the constructor and storing return address in local variable and it ll get destroyed when its scope is over . 

You should store the base address so that you can delete it . 
+1

Qui a downvoted cela? C'est une bonne réponse qui identifie un défaut majeur dans le code OP et offre une solution – Manuel

+0

salut Mac .. désolé je n'ai pas compris. J'utilise simplement numOfRegions pour définir la taille totale du tableau d'objets Region. c'est-à-dire que j'utilise juste la 'valeur' ​​de numOfregions ... n'est-ce pas? – memC

+1

Votre code est correct * sauf * que vous devez stocker votre pointeur dans une variable membre de votre classe (ce que Mac appelle 'm_reg'). Sinon, vous finirez avec une fuite de mémoire et une classe inutile. Quoi qu'il en soit, comme je l'ai dit dans un autre de mes commentaires, vous devriez vraiment utiliser un 'std :: vector ' au lieu de gérer manuellement la mémoire. – Manuel

2

Comment savoir si deux éléments sont identiques ou non? De votre question sur la détection si e1 est déjà là dans les éléments, il semble qu'une map/set/hash pourrait être une meilleure structure de données qu'un vecteur.

Aussi, je crois que c'est push_back, pas pushBack.

+0

L'élément 'nombre' est connu et unique. Donc, je connais cette info. pourriez-vous, s'il vous plaît, illustrer comment implémenter la structure de données alternative que vous décrivez? Je vous remercie! – memC

+1

@memC - la chose la plus facile est probablement d'utiliser un 'std :: set '. Vous devrez surcharger l'opérateur Manuel

+0

@Manuel: Je recommanderais de fournir un type de foncteur de comparaison à la 'std :: set' sauf s'il existe un réel ordre parmi les objets 'element'. Autrement dit, 'operator <' a une sémantique implicite pour les personnes qui lisent le code, et cela peut être source de confusion s'il peut y avoir plus d'un critère d'ordre dans le domaine. (Dans une base de données de téléphone, les personnes peuvent être classées par identifiant d'utilisateur, licence de chauffeur ou numéro de téléphone, que devrait-on implémenter?) –

0

Lorsque vous demandez la syntaxe, je peux immédiatement repérer un point-virgule manquant.

De même, les données publiques (telles que les éléments) ne sont pas vraiment recommandées. Au lieu de cela, essayez d'utiliser les fonctions getter et setter. La variable numOfRegions doit être const int, pas seulement int. En outre, se sent off pour le déclarer dans le c'tor au lieu de dans la déclaration de classe, car c'est un arrangement réglable. Dès que vous voulez passer en revue reg, vous aurez besoin de le redéclarer si vous le gardez comme maintenant.Comme pour la question trois, vous devrez simplement vérifier pour voir si vous pouvez le trouver. Vous aurez probablement besoin d'un bool operator==(const elemt &, const elemt &) pour pouvoir le faire facilement.

+0

Si nous allons lister les erreurs de syntaxe, regardez comment il définit le destructeur de A. Je recommanderais à l'OP de passer son code à travers un compilateur avant de le poster ici. – Manuel

+0

salut e8johan, désolé, j'ai corrigé plusieurs de ces erreurs de syntaxe. Cette syntaxe est-elle correcte: std :: vector elements; ?? – memC

+1

memC, std :: vector est correct, mais à en juger par la section en italique dans le message original, je dirais que cela ne fait pas ce que vous attendez.Si des instances d'elemt sont créées et éliminées ailleurs, vous ne voulez pas un vecteur de copies d'elemt. Un vecteur de pointeurs vers les instances déjà existantes de elemt est suffisant., Donc: std :: vector . –

1

Vous devez détacher la syntaxe de la question de conception. La syntaxe est quelque chose que le compilateur va vérifier et appliquer, mais là encore, vous pourriez obtenir des sémantiques non désirées ...

En vous concentrant sur la conception, quelles sont vos exigences? (Désolé j'ai tendance à lire en diagonale s'il y a plus de quelques lignes, donc j'ai peut-être manqué quelque chose là)

Il ya une classe qui crée/détruit elemt objets, l'allocation dynamique est-elle vraiment une exigence? ou est-ce juste parce que les éléments sont construits avec des données disponibles dans la classe de construction? Si l'allocation dynamique est une exigence, alors il semble que les objets doivent être maintenus par un pointeur (probablement des pointeurs intelligents). Est-ce que la classe qui est destinée à supprimer les objets en garde la trace ou gère-t-elle simplement les objets vers le monde extérieur en attendant que le code utilisateur appelle une fonction deallocator? Les objets elemt sont-ils partagés entre différentes entités? Et il y a d'autres questions que vous devriez considérer ...

Peut-être que vous devriez essayer de reformuler votre question, le code que vous avez posté est essentiellement syntaxiquement correct (juste vérifier avec un compilateur, je n'ai pas), mais sans savoir ce que vous Vraiment vouloir réaliser, vous ne pouvez pas vraiment demander si c'est un bon ou un mauvais design. Décrivez votre vrai problème et demandez ensuite si le code peut être une solution à vos besoins.

+0

merci David Les objets ** elem ** sont gérés par la classe qui les crée. Une exigence? "C'est quelque chose que je suis confus au sujet de ... Je ne sais pas quand utiliser" nouveau "... quelle est son importance .. BTW, j'ai mis en place une meilleure version de cela (merci à Manuel) ... std :: vector reg et ensuite les instances de Region sont ajoutées à ce vecteur en tant que reg.push_back (Region (num)) – memC

+0

@memC: sans contexte, il est difficile d'aider les décisions de conception. en utilisant un «vecteur », cela signifie que conserver des copies différentes (par rapport aux objets partagés) est correct, et que contrôler la durée de vie des objets n'est pas vraiment une responsabilité d'une classe ... Des descriptions de niveau supérieur des problèmes donnent généralement des idées sur ce type de décisions de conception. –

Questions connexes