Reputation: 709
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?
Upvotes: 7
Views: 23537
Reputation: 13005
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)?
Upvotes: 2
Reputation: 20264
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.
Upvotes: 13
Reputation: 548
You can use std::map for this.
http://www.cplusplus.com/reference/map/map/
Upvotes: 1