13

i created a class its name is Student as follows:

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
};

then after i wanted to have a container ( say a vector ) its elements are instances of class Student, but i found myself not able to understand this situation , here is my issue:

first i run this 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;
}

everything is fine and the output is :

Hello, This is a code to learn classes
9

now when i try these 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;
}

i got this output "error" :

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;
}

the output "error" was :

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 )
                                ^

In the first try everything was looking ok , but when i tried the two next options , i received errors , i wish that i can understand what wrong i am doing.

Thanks.

6
  • 1
    First thing, put operators in a function, C++ doesn't allow operator outside a function. Commented Oct 29, 2013 at 12:08
  • If I recall correctly if you have a constructor with parameters, C++ does not create a default constructor, whhich is the reason for "no matching function for call to 'Student::Student()'". So add ´Student() {}´ in the public part of your Student class. Commented Oct 29, 2013 at 12:14
  • 1
    vector <Student> ver[N]; this does not create a vector with N students. It creates an array with N vector<Student>. You want `vector<Student> ver(N); Commented Oct 29, 2013 at 12:17
  • @ExpectoPatronum: Bad idea to have a constructor that does not initialize the object correctly. Also Two phase initialization is also a bad idea. So default constructor for this class is not good idea. Commented Oct 29, 2013 at 14:32
  • 1
    @ExpectoPatronum: Its perfectly fine to have multiple constructors. The problem is leaving the object in a bad (unitialized or undefined) state after the constructor finishes. Commented Oct 29, 2013 at 14:41

6 Answers 6

29

This:

vector <Student> ver[N];

Creates an array of N elements. Each element is vector<Student>. This is not you want. You were probably trying to create a vector of N elements. The syntax for this is:

vector <Student> ver(N);

But you can't use this because your class does not have a default constructor. So your next alternative is to initializae all the objects with the same element.

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

You also tried to create an array of students like this:

Student ver[N];

This will not work. Because it tries to initialize every element in the array with the default constructor. But your class does not have a default constructor. So this will not work. But this is why your original code did work:

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.

The other issues is that you can not run code outside a function(method).
So this will not work:

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

In C++11 you can initialize a vector the same way as an array:

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

If you don't have C++11 or initialization is more complex. Then you need to write a 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));
         }
 };

Now You can place this in global scope and it will auto init.

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

 int main()
 {}

Full solution:

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;
}
Sign up to request clarification or add additional context in comments.

4 Comments

Let me start by saying that your answer was better working partially than all other answers , but i feel either stupid or overwhelmed with options , but i am not able to make it work with all of them, i think that i have a problem in some where maybe with vectors, i am not able to write a complete code to make it work , everytime i change something i end with other kind of errors , Loki can you please edit your answer and make it complete code to see if it works , i feel like lost for now , i am just receiving suggestions but non alone is solving those error messages.
i got this error message test.cpp:104:18: error: 'Student' was not declared in this scope std::vector<Student> vec; ^ test.cpp:104:25: error: template argument 1 is invalid std::vector<Student> vec; ^ test.cpp:104:25: error: template argument 2 is invalid test.cpp: In constructor 'VecWrapper::VecWrapper()': test.cpp:107:13: error: request for member 'reserve' in '((VecWrapper*)this)->Ve cWrapper::vec', which is of non-class type 'int' vec.reserve(N); ^
@mazlor: The hint is in the first 3 words of the error message. You should be able to decipher that.
Now it is working perfect , now i have to go and study wrapper, thank you very much Loki, i appreciate all what you did.
2

The main problem is you are trying to execute a for loop at global scope. It is acceptable to define and initialize variables outside of a function, but using a for loop or assignment operator is not. Put the for loop into main() (and I would recommend you also put N and the vector/student array into main() and everything should work.
Additionally, the compiler is complaining because when you declare Student array[5]; or vector<Student> ver[N]; it is looking for a default constructor for Student called Student(), which just sets default values for a class. You need to provide this inside the Student class; set the id to some value that can never be an actual student ID, something like -1.

1 Comment

Not a good idea to allow the creation of invalid objects. Also vector<Student> ver[N]; is fine. Each of the N vector(s) is empty on construction. So no Student objects are created and thus no constraints are violated.
1

Option #1:

You should replace vector <Student> ver[N] with vector<Student> ver(N)

The std::vector is a class, that represents the vector by himself, you shouldn't create an array of vectors, you should just pass N(vector size) to it's constructor. Check this link

Option #2:

Student ver[N];

is incorrect, since the Default Constructor Student() is invoked N times, but you haven't implement it. So you have to use array initilizer Student ver[5] = {1, 2, 3, 4, 5} or implement the default constructor explicitly.

And of course - the "for" loop has to be used inside function body.

Comments

1
    #include<iostream>

    using namespace std;

    class Student
    {
        private:
        int id;

        public:
        // Mutator
        void setId(int i)
        {
          id = i;
        }
        // Accessor
        int getId()const
        {
          return id;
        }
    };

    int main()
    {
        const unsigned int N = 5;
        Student ver[N];   // Define instances as an array 
        // of the Student class

        int idStudent[N] = { 11, 32, 37, 4, 50};  // Create 
        // one dimensional array with N elements of the 
        // student ID

        for(unsigned int i = 0; i < N; i++ ){ // Assign 
        //student ID for each object of the class
        ver[i].setId(idStudent[i]);}

        cout<< "Hello, This is a code to learn classes : "
        << endl << endl; // Display the student ID

        for(unsigned int i = 0; i < N; i++ ){
        cout<< "Student ID #"  << i+1 << " of "
        << N << " : " << ver[i].getId() << endl;}

        return 0;

    }

Comments

0

This is actually not linked at all with vectors. You just need to move your "for" statement into your main

Comments

0

The solution to the question asked is to create an array of instances of the Student class as Student ver[N]. Next, using the mutator function, setID(int i) to assign the elements from a given student ID in array format ( int idStudent[N] = { 11, 32, 37, 4, 50};) to each perspective instance of the Student class: ver[i].setId(idStudent[i]) and for loop to finish the job.

Last, using the accessor function, ver[i].getID() and the for loop to display the info.

1 Comment

Welcome to SO. Please format the code in the answer explain using comments in code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.