Say I have a vector for class Students, but the requirement of the question states that I cannot put grade together in the constructor, so I will have to work around it.
Is it possible that I have two values in one vector slot?
For example, the class Student and string grade are my arguments.
vector<Student*, string> Students;
So, at the end of the day, if I cout the vector, I should get Student AND the grade in one slot.
Does this work? If so, how do I push_back the value?
Otherwise, is there another way to do this?
Yes it is possible to hold two different types, you can create a vector of union types. The space used will be the larger of the types.
A vector will hold an object of a single type, and only a single type.
Vectors are the dynamic arrays that are used to store data.It is different from arrays which store sequential data and are static in nature, Vectors provide more flexibility to the program. Vectors can adjust their size automatically when an element is inserted or deleted from it. Vectors are not ordered in C++.
This happens because every time we run out of capacity, the vector doubles its capacity. Therefore, if we insert one element when the capacity of the vector is 1 , the vector will double its size to 2 . If we insert one more element, the vector will double its size to 4 .
std::vector<std::pair<Student*, string>> students;
or even better:
std::map<Student*, string> students;
Pushing values:
first case:
students.push_back(std::make_pair(x,y));
even better(as @snps advised):
students.emplace_back(x, y);
second case:
students[x]=y;
Be aware that in the second case you can not add multiple record with the same Student*
value. If you try it will write over the old one.
There are multiple ways of achieving this.
A. Array of structures:
A1. Composition:
class GradedStudent {
Student body;
string grade;
public:
GradedStudent(const string& grade);
// reimplement all methods of `Student`,
// delegating implementations to `body`
};
std::vector<GradedStudent> gradedStudents;
A2. Inheritance (all students have grades):
class Student {
public:
Student();
};
class GradedStudent {
string grade;
public:
GradedStudent(const string& grade);
};
std::vector<GradedStudent*> gradedStudents;
A3. Inheritance + polymorphysm (some students have grades and some don`t):
class Student {
public:
Student();
virtual ~Student();
virtual const string& getGrade() const { return ""; }
};
class GradedStudent : public IStudent {
string grade;
public:
GradedStudent(const string& grade);
virtual string getGrade() const override { return grade; }
};
std::vector<Student*> students;
// non graded students will have empty string as a grade
B. Structure of Arrays approach (separate array for grades):
std::vector<Student*> students;
std::vector<string> grades;
for(int i = 0; i < students.size(); ++i) {
auto* student = students[i];
auto grade = grades[i];
}
C. Associative container (doesn`t honor "use std::vector" requirement):
std::map<Student*, string> students;
for(auto student : students) {
auto* student = student.first;
auto grade = student.second;
}
Those are classic ones. There might be more.
If all students have grades, you should really make grade a member of this class.
P.S. Do you really need to store pointers in a vector (as opposed to storing objects)?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With