web-dev-qa-db-fra.com

créer un vecteur d'instances d'une classe en c ++

j'ai créé une classe dont le nom est Student est la suivante:

class Student
{
 private:
     unsigned int id;                                // the id of the student 
public:   
    unsigned int get_id(){return id;};   
    void set_id(unsigned int value) {id = value;};
    Student(unsigned int init_val) {id = init_val;};   // constructor
    ~Student() {};                                     // destructor
};

puis après avoir voulu avoir un conteneur (disons un vecteur), ses éléments sont des instances de la classe Student, mais je me suis trouvé incapable de comprendre cette situation, voici mon problème:

d'abord, je lance ce code:

#include<iostream>
#include<vector>
using namespace std;

const unsigned int N = 5;

Student ver_list[2] = {7, 9};


int main()
{

  cout<< "Hello, This is a code to learn classes"<< endl;

  cout<< ver_list[1].get_id() << endl;

return 0;
}

tout va bien et le résultat est:

Hello, This is a code to learn classes
9

maintenant, quand j'essaye ces options:

option 1:

#include<iostream>
#include<vector>
using namespace std;

const unsigned int N = 5;

vector <Student> ver[N];             // Create vector with N elements
for(unsigned int i = 0; i < N; ++i )
ver[i].set_id(i); 


int main()
{

  cout<< "Hello, This is a code to learn classes"<< endl;

  cout<< ver[1].get_id() << endl;

return 0;
}

j'ai eu cette sortie "erreur":

test.cpp:26:3: error: expected unqualified-id before 'for'
   for(unsigned int i = 0; i < N; ++i )
   ^
test.cpp:26:27: error: 'i' does not name a type
   for(unsigned int i = 0; i < N; ++i )
                           ^
test.cpp:26:34: error: expected unqualified-id before '++' token
   for(unsigned int i = 0; i < N; ++i )
                                  ^
test.cpp: In function 'int main()':
test.cpp:43:15: error: 'class std::vector<Student>' has no member named 'get_id'

 cout<< ver[1].get_id() << endl;
               ^

option 2:

#include<iostream>
#include<vector>
using namespace std;

const unsigned int N = 5;

Student ver[N];                       // Create one dimensional array with N elements
for(unsigned int i = 0; i < N; ++i )
   ver[i].set_id(i); 


int main()
{

  cout<< "Hello, This is a code to learn classes"<< endl;

  cout<< ver[1].get_id() << endl;

return 0;
}

la sortie "erreur" était:

test.cpp:30:14: error: no matching function for call to 'Student::Student()'
Student ver[5];
             ^
test.cpp:30:14: note: candidates are:
test.cpp:14:2: note: Student::Student(unsigned int)
  Student(unsigned int init_val) {id = init_val;};   // constructor
  ^
test.cpp:14:2: note:   candidate expects 1 argument, 0 provided
test.cpp:7:7: note: Student::Student(const Student&)
 class Student
       ^
test.cpp:7:7: note:   candidate expects 1 argument, 0 provided
test.cpp:31:1: error: expected unqualified-id before 'for'
 for(unsigned int i = 0; i < N; ++i )
 ^
test.cpp:31:25: error: 'i' does not name a type
 for(unsigned int i = 0; i < N; ++i )
                         ^
test.cpp:31:32: error: expected unqualified-id before '++' token
 for(unsigned int i = 0; i < N; ++i )
                                ^

Au premier essai, tout semblait aller bien, mais quand j'ai essayé les deux options suivantes, j'ai reçu des erreurs, j'aimerais pouvoir comprendre ce que je fais de mal.

Merci. 

5
mazlor

Ce:

vector <Student> ver[N];

Crée un tableau d'éléments N. Chaque élément est vector<Student>. Ce n'est pas ce que tu veux. Vous essayiez probablement de créer un vecteur d'éléments N. La syntaxe est la suivante:

vector <Student> ver(N);

Mais vous ne pouvez pas l'utiliser car votre classe n'a pas de constructeur par défaut. Donc, votre alternative suivante consiste à initialiser tous les objets avec le même élément.

vector <Student> ver(N, Student(0));

Vous avez également essayé de créer un tableau d’étudiants comme celui-ci:

Student ver[N];

Cela ne fonctionnera pas. Parce qu'il essaie d'initialiser chaque élément du tableau avec le constructeur par défaut. Mais votre classe n'a pas de constructeur par défaut. Donc cela ne fonctionnera pas. Mais c’est pourquoi votre code original a fonctionné:

Student ver_list[2] = {7, 9};  // Here you are using the constructor for your object.
                               // It uses the normal constructor you provided not the default one.

Les autres problèmes sont que vous ne pouvez pas exécuter de code en dehors d'une fonction (méthode).
Donc cela ne fonctionnera pas:

for(unsigned int i = 0; i < N; ++i )
    ver[i].set_id(i); 

En C++ 11, vous pouvez initialiser un vecteur de la même manière qu'un tableau:

vector<Student>  ver = { 0, 1, 2, 3, 4, 5};

Si vous n'avez pas C++ 11 ou l'initialisation est plus complexe. Ensuite, vous devez écrire un wrapper.

class VecWrapper
{
     public:
         std::vector<Student>   ver;
         VecWrapper()
         {
            ver.reserve(N);
            for(unsigned int i = 0; i < N; ++i )
                ver.Push_back(Student(i));
         }
 };

Maintenant, vous pouvez placer ceci dans la portée globale et il sera auto init.

 VecWrapper   myData;  // myData.vec  initializaed before main entered.

 int main()
 {}

Solution complète:

Option 2:

#include<iostream>
#include<vector>
using namespace std;

const unsigned int N = 5;

// The following is not correct
// This creates an arrya of `N` elements each element is `vector <Student>`
//
// vector <Student> ver[N];             // Create vector with N elements
// 

// The following lines are not allowed.
// All code has to be inside a function.
//
// for(unsigned int i = 0; i < N; ++i )
// ver[i].set_id(i); 


// What you want is:
//    I use the following because it is unclear if you have C++11 or not.  
class VecWrapper
{
   public:
     std::vector<Student>   vec;
     VecWrapper()
     {
        vec.reserve(N);
        for(unsigned int i = 0; i < N; ++i )
            vec.Push_back(Student(i));
     }
};
VecWrapper   myData;  // myData.vec 
int main()
{

  cout<< "Hello, This is a code to learn classes"<< endl;

  cout<< myData.vec[1].get_id() << endl;

return 0;
}
14
Martin York

Le problème principal est que vous essayez d'exécuter une boucle for à une portée globale. Il est acceptable de définir et d’initialiser des variables en dehors d’une fonction, mais l’utilisation d’un opérateur de boucle ou d’affectation ne l’est pas. Mettez la boucle for dans main () (et je vous recommanderais également de mettre N et le tableau vectoriel/étudiant dans main () et tout devrait fonctionner.
En outre, le compilateur se plaint parce que lorsque vous déclarez Student array[5]; ou vector<Student> ver[N];, il recherche un constructeur par défaut pour Student appelé Student (), qui ne fait que définir les valeurs par défaut d'une classe. Vous devez fournir ceci dans la classe des étudiants; définissez l'identifiant sur une valeur qui ne peut jamais être un identifiant d'étudiant réel, quelque chose comme -1.

2
Zach Stark

Option 1: 

Vous devez remplacer vector <Student> ver[N] par vector<Student> ver(N)

Le std :: vector est une classe, qui représente le vecteur lui-même, vous ne devriez pas créer un tableau de vecteurs, vous devriez simplement passer N (taille du vecteur) à son constructeur. Cochez cette link

Option 2:

Student ver[N];

est incorrect, car le constructeur par défaut Student () est appelé N fois, mais vous ne l'avez pas implémenté. Vous devez donc utiliser array initilizer Student ver[5] = {1, 2, 3, 4, 5} ou implémenter explicitement le constructeur par défaut.

Et bien sûr, la boucle "pour" doit être utilisée dans le corps de la fonction. 

1
Alexey Teplyakov

En réalité, cela n’est pas du tout lié à des vecteurs. Il vous suffit de déplacer votre "pour" dans votre déclaration principale.

0
Thomas Benard