How to input an object in C++? - c++

Hi the code below is a simple class example in C++
#include <iostream>
using namespace std;
class Car { // The class
public: // Access specifier
string brand; // Attribute
string model; // Attribute
int year; // Attribute
Car(string x, string y, int z) { // Constructor with parameters
brand = x;
model = y;
year = z;
}
};
int main() {
// Create Car objects and call the constructor with different values
Car carObj1("BMW", "X5", 1999);
Car carObj2("Ford", "Mustang", 1969);
// Print values
cout << carObj1.brand << " " << carObj1.model << " " << carObj1.year << "\n";
cout << carObj2.brand << " " << carObj2.model << " " << carObj2.year << "\n";
return 0;
}
// W3Schools
As I see it, the way you can define an object is to write it in code like : <ClassName> <ObjectName>
Now my question is : Is there a way to input an object? like cin >> ObjectName;
And after we entered the name of object, we enter the parameters.
Is it possible at all?

You can't enter an object name from the command line, however, you can create a default constructed object and then fill its' properties from the input by overloading operator>>.
class Car {
public:
Car() = default;
// ...
};
std::istream& operator>>(std::istream& in, Car& car) {
in >> car.brand >> car.model >> car.year;
return in;
}
int main() {
Car carObj1;
cout << "Enter a car brand, model, and year: ";
cin >> carObj1;
// ...
}

Yes, There is operator overloading in C++ and you can overload both << and >> operators. Here is an example code:
#include <iostream>
using namespace std;
class Car { // The class
public: // Access specifier
string brand; // Attribute
string model; // Attribute
int year; // Attribute
Car(string x, string y, int z) { // Constructor with parameters
brand = x;
model = y;
year = z;
}
Car() = default;
void Carinput(std::istream& is)
{
is >> brand >> model >> year;
}
void carOutput(std::ostream& os) const
{
os << brand << " " << model << " " << year << std::endl;
}
};
std::istream &operator>>(std::istream &is,Car &car)
{
car.Carinput(is);
return is;
}
std::ostream &operator<<(std::ostream &os,const Car &car)
{
car.carOutput(os);
return os;
}
int main() {
// Create Car objects and call the constructor with different values
Car carObj1("BMW", "X5", 1999);
Car carObj2("Ford", "Mustang", 1969);
// Print values
cout << carObj1.brand << " " << carObj1.model << " " << carObj1.year << "\n";
cout << carObj2.brand << " " << carObj2.model << " " << carObj2.year << "\n";
std::cout << "\n*============================================*\n"
<< std::endl;
std::cout << "Your input:" << std::endl;
Car carObj3;
std::cin >> carObj3;
std::cout << carObj3;
return 0;
}

This is one of the ways of doing it:
#include<iostream>
#include<vector>
class Car
{
public:
Car( const std::string& brand, const std::string& model, int year )
: m_brand( brand ), m_model( model ), m_year( year ) // initialize members like this
{
}
std::string m_brand;
std::string m_model;
int m_year;
};
int main ()
{
std::vector< Car > cars; // use an std::vector to store the objects
std::string brand( "" );
std::string model( "" );
std::string year( "" );
std::cout << "How many cars do you want to add? ";
std::string count( "" );
std::getline( std::cin, count ); // get input as string using std::getline()
int carCount { std::stoi( count ) }; // converts it to type int before
// assigning it to carCount
cars.reserve( carCount ); // reserve some space in vector to avoid
// unnecessary allocations and slowdowns
for ( int idx = 0; idx < carCount; ++idx )
{
std::cout << "Enter the brand name of car number " << idx + 1 << ": ";
std::getline( std::cin, brand );
std::cout << "Enter the model name of car number " << idx + 1 << ": ";
std::getline( std::cin, model );
std::cout << "Enter the production year of car number " << idx + 1 << ": ";
std::getline( std::cin, year );
cars.emplace_back( Car( brand, model, std::stoi( year ) ) ); // push the new Car
} // instance to the
// vector called cars
std::cout << '\n';
for ( int idx = 0; idx < carCount; ++idx )
{
std::cout << "Info for car number " << idx + 1 << ": "
<< cars[ idx ].m_brand << " " << cars[ idx ].m_model << " " << cars[ idx ].m_year << "\n";
}
return 0;
}
Here is the output:
How many cars do you want to add? 2
Enter the brand name of car number 1: Porsche
Enter the model name of car number 1: GT3 RS
Enter the production year of car number 1: 2019
Enter the brand name of car number 2: BMW
Enter the model name of car number 2: M6
Enter the production year of car number 2: 2016
Info for car number 1: Porsche GT3 RS 2019
Info for car number 2: BMW M6 2016
But keep in mind that this class still needs a lot of work like adding member functions (like getters and setters) etc. So this is not how I write classes. I just wanted to keep it simple so you can easily understand the concepts.

Related

Why do I get the error "use of deleted function 'class : : class()"

#include <iostream>
using namespace std;
class student
{
protected:
string name;
int roll;
int age;
public:
student(string n, int r, int a)
{
name = n;
roll = r;
age = a;
}
};
class test : public student
{
protected:
int sub[5];
public:
void marks()
{
cout << "Enter marks in 5 subjects: " << endl;
cin >> sub[0] >> sub[1] >> sub[2] >> sub[3] >> sub[4];
}
void display()
{
cout << "Name : " << name << "\nRoll number : " << roll << "\nAge: " << age << endl;
cout << "Marks in 5 subjects : " << sub[0] << ", " << sub[1] << ", " << sub[2] << ", " << sub[3] << ", " << sub[4] << endl;
}
};
class sports
{
protected:
int sportmarks;
public:
sports(int sm)
{
sportmarks = sm;
}
};
class result : public test, public sports
{
int tot;
float perc;
public:
void calc()
{
tot = sportmarks;
for(int i = 0; i < 5; i++)
tot = tot + sub[i];
perc = (tot / 600.0) * 100;
cout << "Total: " << tot << "\nPercentage: " << perc << endl;
}
};
int main()
{
student ob1("Name", 781, 19);
sports ob2(78);
result ob;
ob.marks();
ob.display();
ob.calc();
}
I've been asked to use parameterized constructors to do this problem and notice I get these errors when I use constructors. Sorry if this post is inconvenient to read. In what way can I run this code while creating objects from parameterized constructors?
use of deleted function 'result::result()'
use of deleted function 'test::test()'.
no matching function for call to 'student::student()'
no matching function for call to 'sports::sports()'
student and sports have user-defined constructors, so the compiler does not generate default constructors for them.
test and result have no user-defined constructors, so the compiler will generate default constructors for them. However, since student and sports have no default constructors, the generated default constructors are marked delete'd as they are not usable. That is why you get errors.
To make your main() compile as-is, you need to define your own default constructors for test and result which pass explicit parameter values to their base classes, eg:
#include <iostream>
using namespace std;
class student
{
protected:
string name;
int roll;
int age;
public:
student(string n, int r, int a)
{
name = n;
roll = r;
age = a;
}
};
class test : public student
{
protected:
int sub[5];
public:
test() : student("", 0, 0) {}
void marks()
{
cout << "Enter marks in 5 subjects: " << endl;
cin >> sub[0] >> sub[1] >> sub[2] >> sub[3] >> sub[4];
}
void display()
{
cout << "Name : " << name << "\nRoll number : " << roll << "\nAge: " << age << endl;
cout << "Marks in 5 subjects : " << sub[0] << ", " << sub[1] << ", " << sub[2] << ", " << sub[3] << ", " << sub[4] << endl;
}
};
class sports
{
protected:
int sportmarks;
public:
sports(int sm)
{
sportmarks = sm;
}
};
class result : public test, public sports
{
int tot;
float perc;
public:
result() : test(), sports(0) {}
void calc()
{
tot = sportmarks;
for(int i = 0; i < 5; i++)
tot = tot + sub[i];
perc = (tot / 600.0) * 100;
cout << "Total: " << tot << "\nPercentage: " << perc << endl;
}
};
int main()
{
student ob1("Name", 781, 19);
sports ob2(78);
result ob;
ob.marks();
ob.display();
ob.calc();
}
Online Demo
However, this is not very useful, so I would suggest tweaking result's constructor to take the student and sports objects you have already created beforehand, and pass them to the base class copy constructors, which the compiler will generate for you, eg:
#include <iostream>
using namespace std;
class student
{
protected:
string name;
int roll;
int age;
public:
student(string n, int r, int a)
{
name = n;
roll = r;
age = a;
}
};
class test : public student
{
protected:
int sub[5];
public:
test(const student &s) : student(s) {}
void marks()
{
cout << "Enter marks in 5 subjects: " << endl;
cin >> sub[0] >> sub[1] >> sub[2] >> sub[3] >> sub[4];
}
void display()
{
cout << "Name : " << name << "\nRoll number : " << roll << "\nAge: " << age << endl;
cout << "Marks in 5 subjects : " << sub[0] << ", " << sub[1] << ", " << sub[2] << ", " << sub[3] << ", " << sub[4] << endl;
}
};
class sports
{
protected:
int sportmarks;
public:
sports(int sm)
{
sportmarks = sm;
}
};
class result : public test, public sports
{
int tot;
float perc;
public:
result(const student &s, const sports &sp) : test(s), sports(sp) {}
void calc()
{
tot = sportmarks;
for(int i = 0; i < 5; i++)
tot = tot + sub[i];
perc = (tot / 600.0) * 100;
cout << "Total: " << tot << "\nPercentage: " << perc << endl;
}
};
int main()
{
student ob1("Name", 781, 19);
sports ob2(78);
result ob(ob1, ob2);
ob.marks();
ob.display();
ob.calc();
}
Online Demo

Accessing multiple instances of a class in C++

I am creating a menu for a restaurant that can have 5 dishes of each category. So far I have created a class for meat dishes and I'm able to add up to 5 dishes, each with a unique identifier. What I am having trouble with is accessing the objects after they have been created.
(There will be multiple categories hence why there is a switch statement with only one case so far).
For example, how would I implement a way to change the description of the second dish?
Here is my code so far:
meat.h
class Meat{
private:
int meatNumber;
std::string meatCategory;
std::string meatDescription[MAX_ITEMS];
double meatPrice[MAX_ITEMS];
public:
Meat();
//setter functions
int setMeatNumber();
std::string setMeatDescription();
double setMeatPrice();
//getter functions
int getMeatNumber();
std::string getMeatCategory();
std::string getMeatDescription(int i);
double getMeatPrice(int i);
};
meat.cpp
#include "Meat.h"
//constructor
Meat::Meat() {
meatNumber = 0;
meatCategory = "Meat";
meatDescription[MAX_ITEMS] = "No description written.";
meatPrice[MAX_ITEMS] = 0.0;
}
//setter functions
int Meat::setMeatNumber(){
static int counter = 1;
meatNumber = counter++;
}
std::string Meat::setMeatDescription(){
int i = 0;
std::cout << "Please enter a short description: " << std::endl;
std::cin >> meatDescription[i];
return meatDescription[i];
}
double Meat::setMeatPrice(){
int i = 0;
std::cout << "Please set the price in a 00.00 format: " << std::endl;
std::cout << "£";
while(!(std::cin >> meatPrice[i])){
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cout << "Error. Please enter a number: ";
}
return meatPrice[i];
}
//getter functions
int Meat::getMeatNumber() { return meatNumber; }
std::string Meat::getMeatCategory() { return meatCategory; }
std::string Meat::getMeatDescription(int i) {return meatDescription[i]; }
double Meat::getMeatPrice(int i) { return meatPrice[i]; }
main.cpp
#include <iostream>
#include "Meat.h"
int main() {
int choice;
std::cout << "Menu Creation Terminal\n\n" << std::endl;
std::cout << "\t Welcome\nto Wrapid™ Restaurants\n\n" << std::endl;
std::cout << "1. Add Meat Dish\n2. Add Fish Dish\n3. Add Vegetarian Dish\n4. Add Drink\n"
"5. Edit Current Menu\n6. Quit\n\n" << std::endl;
std::cout << "Please select an option: ";
std::cin >> choice;
switch (choice) {
case 1:
{
int option = true;
int count = 0, i;
Meat meatDish;
std::cout << "Meat Dishes" << std::endl;
while (true) {
meatDish.setMeatNumber();
meatDish.setMeatDescription();
meatDish.setMeatPrice();
//functions to add details to dish
std::cout << "You have added the following dish: " << std::endl;
std::cout << "Item number: \n" << meatDish.getMeatNumber() << std::endl;
std::cout << "Item Category: \n " << meatDish.getMeatCategory() << std::endl;
std::cout << "Item Description: \n" << meatDish.getMeatDescription(i) << std::endl;
std::cout << "Item Price: \n £" << meatDish.getMeatPrice(i) << std::endl;
std::cout << "Would you like to add another item? Press 1 for yes or 2 for no: " << std::endl;
std::cin >> option;
count += 1;
if (count == 5) {
std::cout << "Error. Exceeded maximum items.";
break;
} //breaks out of loop if more than 5 items
if (option == 2) { break; } //breaks out of loop when user is finished adding items
}//while loop to contain menu
}//brace for scope of case 1
}
return 0;
}
As you are using c++ class Meat you can use [] to instantiate N items
for example 5 objects
Meat meats[5];
If you want to modify 2nd object then
meats[1].setMeatDescription(<pass argument>);
You need to change that method using this keyword
this->meatDescription = <pass argument>;
No need to create meatDescription[] as an array
use this code https://pastebin.com/bCkzbFZV you can use meats[i].getMeatDescription()
You could create a new class called DishesContainer. This class could have :
a private std::vector => it will hold every instance
a public function to create a new dish
a public function to change any type of value inside a dish meat.
For exemple to change the description
class DishContainer{
public:
void ChangeDescription(int indexMeat, std::string newDescription){
meats_[indexMeat].setMeatDescription(newDescription);
}
private:
std::vector<Meat> meats_;
}

How to fill structs within a class from a file?

I have an assignment where we need to create a class object that has many different variables, one of which being a struct. I can't figure out how to fill the struct from my setter function. I've attached some codes snippets I've pulled out of my code. my count_file_line function returns an int value of however many lines are in a txt file. I'm also really new to coding and have been struggling so if it's an obvious answer, sorry
When I run the program and try to cout teachers[I].password from within the setter function, nothing shows up (the "Flag" does show up)
struct teacher{
int id;
string password;
string first_name;
string last_name;
};
void University::set_teachers(ifstream& inFile){
int amountOfTeachers = count_file_lines(inFile);
this->teachers = new teacher[amountOfTeachers];
for(int i = 0; i < amountOfTeachers; i++){
inFile >> teachers[i].password;
inFile >> teachers[i].first_name;
inFile >> teachers[i].last_name;
cout << "Flag" << endl;
}
}
What you're trying to accomplish is a "de-serialization" of a sequence of teacher objects.
You may be interested in:
Is it possible to serialize and deserialize a class in C++?
for some general-purpose solutions. Note those may (or may not) be a bit "heavy-weight" for what you need to achieve.
Example of using tell, don't ask:
#include <iostream>
using std::cout, std::cerr, std::endl;
#include <iomanip>
using std::setw, std::setfill;
#include <fstream>
using std::ifstream, std::istream; // std::ofstream;
#include <sstream>
using std::stringstream;
#include <string>
using std::string, std::to_string;
#include <cstdint>
#include <cassert>
// stub - this function implemented and tested elsewhere
int count_file_lines(ifstream& inFile)
{
if (!inFile.good())
cerr << "\n !infile.good()" << endl;
return 5; // for test purposes
}
struct teacher
{
private:
int id; // unique number in record order
string password;
string first_name;
string last_name;
static int ID; // init value below
// note: On my system each string is 32 bytes in this object,
// regardless of char count: the chars are in dynamic memory
public:
teacher() : id(++ID) // password, first_name, last_name
{ } // default init is empty string
~teacher() = default; // do nothing
void read(istream& inFile) // tell instance to read next record
{
inFile >> password;
inFile >> first_name;
inFile >> last_name;
}
void show()
{
cout << "\n show id:" << id
<< "\n pw :" << password
<< "\n fn :" << first_name
<< "\n ln :" << last_name
<< endl;
}
};
int teacher::ID = 0; // compute unique ID number for each record
And a demo of input and output (teacher::read(), teacher::show())
Note use of "stringstream ss;". It is filled using a for loop, and passed to each teacher object using "teacher.read()".
Then the teacher values are echo'd to output using "teacher.show()"
class F834_t
{
teacher* teachers = nullptr; // do not yet know how many
ifstream inFile; // declared, but not opened
uint amountOfTeachers = 0;
stringstream ss; // for debug / demo use
public:
// use default ctor, dtor
F834_t() = default;
~F834_t() = default;
int exec(int , char** )
{
// open infile to count lines
amountOfTeachers = static_cast<uint>(count_file_lines(inFile)); // use working func
cout << "\n teacher count: " << amountOfTeachers << "\n "; // echo
// init ss with 5 values
for (uint i=1; i<=amountOfTeachers; ++i)
ss << " pw" << i << " fn" << i << " ln" << i << " ";
cout << ss.str() << endl;
teachers = new teacher[amountOfTeachers]; // allocate space, invoke default ctor of each
assert(teachers);
cout << "\n teachers: " << setw(4) << sizeof(teachers) << " (pointer bytes)"
<< "\n a teacher: " << setw(4) << sizeof(teacher) << " (teacher bytes)"
<< "\n size of all: " << setw(4) << (amountOfTeachers * sizeof(teacher))
<< " ( " << setw(3) << sizeof(teacher) << " * " << setw(3) << amountOfTeachers << ')'
<< endl;
// reset stream to start of inFIle, maybe close/open inFile
for (uint i=0;i<amountOfTeachers; ++i)
{
assert(ss.good()); // (inFile.good());
teachers[i].read(ss); // (inFile); // tell the object to read the file
}
for (uint i=0;i<amountOfTeachers; ++i)
{
teachers[i].show(); // tell the object to show its contents
}
return 0;
}
}; // class F834_t
int main(int argc, char* argv[])
{
F834_t f834;
return f834.exec(argc, argv);
}
Output - note that a much simplified input stream is created on the fly, and is echo'd early in this output.
teacher count: 5
pw1 fn1 ln1 pw2 fn2 ln2 pw3 fn3 ln3 pw4 fn4 ln4 pw5 fn5 ln5
teachers: 8 (pointer bytes)
a teacher: 104 (teacher bytes)
size of all: 520 ( 104 * 5)
show id:1
pw :pw1
fn :fn1
ln :ln1
show id:2
pw :pw2
fn :fn2
ln :ln2
show id:3
pw :pw3
fn :fn3
ln :ln3
show id:4
pw :pw4
fn :fn4
ln :ln4
show id:5
pw :pw5
fn :fn5
ln :ln5

How to debug "ISO C++ forbids declaration of 'car' with no type"?

I am trying to figure out why I keep getting this error on Dev C++. I don't seem to get any errors when I use computers from my school, so I was wondering if I have missed something here.
[Error] ISO C++ forbids declaration of 'car' with no type -f
permissive
Code:
#include <iostream>
#include <string>
using namespace std;
class Car //class definition
{
private: int modelYr; string model; int speed;
public:
car(int year, string brand)
{ modelYr=year; model=brand; speed=0;} //Constructor
void accelerate() {speed = speed + 5;} //accelerate +5mph (mutator)
void brake() {speed = speed - 5;} //brake -5mph (mutator)
int get_modelYr() const {return modelYr;} //returns model year (accessor)
string get_model() const {return model;} //returns model name (accessor)
int getspeed() const {return speed;} //returns current speed (accessor)
};//end of class definition (note the semicolon ;)
int main() {
Car vehicle; //create a vehicle from class Car
string carModel;//car model to be input by user
int carYear; //car year to be input by user
const string line = "\n-------------------\n"; //used to display a line
cout <<"Enter car model year (2000-current): ";
while(! (cin >> carYear) || (carYear < 2000) ) //carYear validation
{ //checking for numeric year 2000 or later
cin.clear();cin.ignore(10000,'\n');
cout<<"sorry you must enter car year 2000 or later :"<<flush;
} //while loop validation ends
cout <<"Enter car model (example: GMC): "; cin >> carModel;
vehicle.car(carYear,carModel);
cout << line << "Starting speed for your " << vehicle.get_modelYr()
<< " " << vehicle.get_model() << " is " << vehicle.getspeed() << " mph" <<line;
for(int count=0;count<5;count++) //accelerate five times
{ vehicle.accelerate();
cout << "***ACCELERATING***\nSpeed is currently:"<< vehicle.getspeed() << endl;
}//end acceleration
for ( int count=0;count<5 ;count++ )
{vehicle.brake();
cout << "***BRAKING***\nSpeed is currently: " << vehicle.getspeed() << endl;
}
cout << line << "Ending speed for your " << vehicle.get_modelYr()
<< " " << vehicle.get_model() << " is " << vehicle.getspeed() <<" mph"<< line;
return(0);
}//end of main program
Your constructor must be named the same as your class.
#include <iostream>
#include <string>
using namespace std;
class Car //class definition
{
private: int modelYr; string model; int speed;
public:
Car(int year, string brand)
{ modelYr=year; model=brand; speed=0;} //Constructor
void accelerate() {speed = speed + 5;} //accelerate +5mph (mutator)
void brake() {speed = speed - 5;} //brake -5mph (mutator)
int get_modelYr() const {return modelYr;} //returns model year (accessor)
string get_model() const {return model;} //returns model name (accessor)
int getspeed() const {return speed;} //returns current speed (accessor)
};//end of class definition (note the semicolon ;)
int main() {
Car vehicle; //create a vehicle from class Car
string carModel;//car model to be input by user
int carYear; //car year to be input by user
const string line = "\n-------------------\n"; //used to display a line
cout <<"Enter car model year (2000-current): ";
while(! (cin >> carYear) || (carYear < 2000) ) //carYear validation
{ //checking for numeric year 2000 or later
cin.clear();cin.ignore(10000,'\n');
cout<<"sorry you must enter car year 2000 or later :"<<flush;
} //while loop validation ends
cout <<"Enter car model (example: GMC): "; cin >> carModel;
vehicle.car(carYear,carModel);
cout << line << "Starting speed for your " << vehicle.get_modelYr()
<< " " << vehicle.get_model() << " is " << vehicle.getspeed() << " mph" <<line;
for(int count=0;count<5;count++) //accelerate five times
{ vehicle.accelerate();
cout << "***ACCELERATING***\nSpeed is currently:"<< vehicle.getspeed() << endl;
}//end acceleration
for ( int count=0;count<5 ;count++ )
{vehicle.brake();
cout << "***BRAKING***\nSpeed is currently: " << vehicle.getspeed() << endl;
}
cout << line << "Ending speed for your " << vehicle.get_modelYr()
<< " " << vehicle.get_model() << " is " << vehicle.getspeed() <<" mph"<< line;
return(0);
}//end of main program

Setting a string value to none when a class related to it is deleted

I need help with something which I believe is simple. I can assign a student to a project. But when I delete the project, the student is still keeping the project name. I'm thinking of just renaming it back to "None" but I have no idea on how to do that. Help?
Edit
map<int, Student> mstore and vector<int> storeid added.
#include <iostream>
#include <string>
#include <vector>
#include <cstdlib>
#include <map>
using namespace std;
class Human {
public:
virtual void print() const = 0;
};
class Student : public Human {
protected:
string studname;
int studId;
string project;
public:
Student();
Student (string studname, int studId) : studname("Unknown"), studId(0), project("None")
{
cout << "A student is created: Name = " << studname
<< ". Id = " << studId << endl;
}
virtual void print() const {
cout << "Name = " << studname << ". Id = " << studId << ". Project = " << project <<endl; }
void setSName (string sname) { studname = sname; }
void setSID (int sID) { studId = sID; }
void printStudentInfo() const;
void printStudentInfoline() const;
};
void Student::printStudentInfo() const
{
cout << "\nStudent name: " << studname << endl;
cout << "Student ID: " << studId << endl;
cout << "Project: " << project << endl;
}
void Student::printStudentInfoline() const
{
cout << studId << ", " << studname << ", " << project << endl;
}
class Project {
protected:
string projname;
public:
vector <Student> students;
vector <int> storeid;
Project (string projname) : projname(projname) { cout << "Project " << projname << " created" << endl;}
void setPName (string projname) { this->projname = projname; }
void add (int& sid)
{
//student.setProject (projname);
storeid.push_back(sid);
}
int returnid(int& a)
{
return storeid[a];
}
int returnsize()
{ return storeid.size(); }
void printproj() const {
cout << endl << projname << " list: \n";
cout << "Student(s) : " << endl;
for (int i = 0; i < storeid.size(); i++){
cout << storeid[i] << endl;
}
}
void printprojname() const {
cout << projname << endl;
}
};
int main() {
string StudentName;
string ProjectName;
int Studentid;
Student *s1;
Project *p1;
vector<Student> store;
vector<Project> projstore;
map<int, Student> mstore;
map<int, Student>::const_iterator itr;
for (int n=0; n<3; n++) //loop to create 3 students
{
cout <<"Enter name : ";
getline(cin, StudentName);
cout <<"Enter ID : ";
cin >> Studentid;
s1 = new Student(StudentName, Studentid);
s1->setSName(StudentName);
s1->setSID(Studentid);
store.push_back(*s1);
mstore.insert(make_pair(Studentid, *s1));
cin.get();
}
//print map
for(itr=mstore.begin(); itr!=mstore.end() ;++itr)
itr->second.printStudentInfo();
//itr=mstore.begin()+2;
//itr.print();
cout << "Enter project name: ";
getline(cin, ProjectName);
p1 = new Project(ProjectName);
p1->setPName(ProjectName);
//Assigning student to project
cout << endl;
cout << "How many students? :" ;
int y;
cin >> y;
for ( int i = 0; i < y; i++){
cout << "Who would you like to add to this project?" << endl;
int x = 1;
for(itr=mstore.begin(); itr!=mstore.end() ;++itr)
itr->second.printStudentInfoline();
int insID;
cout << "Enter ID number: ";
cin >> insID;
p1->add(insID);
/*
for ( it = store.begin(); it != store.end(); ++it ) {
// For each friend, print out their info
cout << x << ". ";
it->printStudentInfoline();
x++;
}
x = 1;
int insS;
cout << "Enter number: ";
cin >> insS;
p1->add(store[(insS-1)]); //stores selected student into the object
*/
cout << "\nAdding Student done\n" << endl;
}
projstore.push_back(*p1);
//Mstore finds for related ids and displays them accordingly
cout << "print project"<< endl;
vector<Project>::iterator pt;
for ( pt = projstore.begin(); pt != projstore.end(); ++pt ) {
pt->returnsize();
for (int i=0; i <pt->returnsize(); i++){
cout << pt->returnid(i) << endl;
itr=mstore.find(pt->returnid(i));
itr->second.printStudentInfo();
}
}
cout << endl;
cout << "Deleting project" << endl;
cout << "What would you like to remove?" << endl;
int x = 1;
//storeid will display ids. How do I link them to `store` map?
for ( pt = projstore.begin(); pt != projstore.end(); ++pt ) {
cout << x << ". ";
pt->printprojname();
x++;
}
//Now to delete the selected project
int delP;
cout << "Enter number: ";
cin >> delP;
cin.ignore();
system("pause");
projstore.erase(projstore.begin()+delP-1);
// Students
cout << "\n Current students" << endl;
for(itr=mstore.begin(); itr!=mstore.end() ;++itr)
itr->second.printStudentInfo();
}
Look at how you add a Student to a Project:
void add (Student& student)
{
student.setProject (projname);
students.push_back (student); // <-- AHA!
}
First you assign the Project name to the Student, then the Project stores a copy of the Student. After that, the Project has no link to the original Student, and can't inform him/her of its own demise when the time comes.
You'll have to rethink this design; there are three major options: 1) the Students can look up their respective Projects in the store, 2) the Project can look up its Students in the students vector, or 3) the Project owns the Students (in which case they should probably be GraduateStudents).
EDIT:
If that's the way you want to do it, use map<int, Student> store to store the Students, using ID number as an index. Then a Project can have a vector<int> (or set<int>) of student ID numbers. It can look Students up in the store with ease.
EDIT:
To print out the entire collection of students:
for(map<int, Student>::const_iterator itr=store.begin(); itr!=store.end() ;++itr)
itr->second.print();
EDIT:
If the Project has a vector<int> of student ID numbers, then what argument do you think Project::add(?) should take?
EDIT:
The Project can act on a Student by means of the student ID number and access to mstore:
// in Project:
mstore[id].whatever()
EDIT:
Sometimes asking the right question -- or in this case, phrasing the question correctly -- is half the battle. 'Now how do I change "None" to the inserted project name?' A better way to put it is 'How does the Project change one of its Student's project from "None" to projname?' Once you put it that way, the answer is almost obvious:
// in Project:
mstore[id].setSProject(projname);
Note that Student does not yet have setSProject(string), you'll have to add it. Also, note that this solution is not ideal since 1) anybody can change a Student's project, and 2) a Student's project need not actually be the name of a real Project. There is more than one way to deal with these problems.