Adding Setters to a function template - c++

I am trying to add setter to my project as a requirement but am stuck on making it work. I commented out the areas I have to add it but everything I have looked up has not worked. I know I am close but everything seems to not work.
#include "pch.h"
#include <string>
#include <conio.h>
#include <iostream>
using namespace std;
template <class T>
class Holder
{
private:
T thing;
int number; //add an integer data member that stores the number of data members of whatever class is stored in "thing"
public:
void standardInput();
void standardOutput();
void setNumber(int); // declare a setter function for the new data member
};
template <class T>
void Holder<T>::standardInput()
{
cout << endl;
cout << "You will be asked to enter " << n.setNumber << " items" << endl; // a line of output that use the data member with the number
cin >> Holder<T>::thing;
}
template <class T>
void Holder<T>::standardOutput()
{
cout << endl;
cout << "Here's the data you requested: " << endl;
cout << Holder<T>::thing << endl;
}
template<class T>
void Holder<T>::setNumber(int n) //implement the setter function for the new data member
{
setNumber = n;
}
// This is the first of two custom classes
class Student
{
friend ostream& operator<<(ostream&, Student&);
friend istream& operator>>(istream&, Student&);
private:
string name;
double tuiton;
};
ostream& operator<<(ostream& out, Student& a)
{
out << "The Student " << a.name << " Tuiton is: " << a.tuiton << endl;
return out;
}
istream& operator>>(istream& in, Student& a)
{
cout << "Enter the name of student: ";
in >> a.name;
cout << "What is the Price of tuiton? ";
in >> a.tuiton;
return in;
}
// This is the second of two custom classes
class FastFood
{
friend ostream& operator<<(ostream&, FastFood&);
friend istream& operator>>(istream&, FastFood&);
private:
int valueNumber;
double cost;
};
ostream& operator<<(ostream& out, FastFood& a)
{
out << " The Combo Number is " << a.valueNumber << " .It costs " << a.cost << endl;
return out;
}
istream& operator>>(istream& in, FastFood& a)
{
cout << "What is the Combo number? ";
in >> a.valueNumber;
cout << "Enter cost: ";
in >> a.cost;
return in;
}
int main()
{
cout << "For an integer: " << endl;
Holder<int> val;
// use the setter to store 1.
val.standardInput();
val.standardOutput();
cout << "For a Student:" << endl;
Holder<Student> aCollegeStudent;
// use the setter to store 2.
aCollegeStudent.standardInput();
aCollegeStudent.standardOutput();
Holder<FastFood> vMeal;
// use the setter to store 3.
vMeal.standardInput();
vMeal.standardOutput();
cout << endl;
system("pause");
return 0;
}
This is supposed to ask the integer along with the student and fastfood information. I required to add a setter in the template but wont need to use a getter due to standard input and output just cant figure out the right way to do it.

Related

C++ - Throw Erorr Message

The main() function should display an appropriate
thrown error message if non-numeric or negative values are entered for any of
the data members.
can someone help me to write the main function
here is my code
#include <iostream>
using namespace std;
class RealEstate
{
private:
int price;
int bedroomNumb;
int bathsNumb;
public:
RealEstate(int p, int bed, int bath)
{
price = p;
bedroomNumb = bed;
bathsNumb = bath;
}
friend ostream &operator<<(ostream &out, const RealEstate &r);
friend istream &operator>>(istream &in, RealEstate &r);
};
istream &operator>>(istream &in, RealEstate &r)
{
cout << "Enter Real Estate Price: ";
in >> r.price;
cout << "Enter Numbers of Bedroom: ";
in >> r.bedroomNumb;
cout << "Enter Numbers of Baths: ";
in >> r.bathsNumb;
return in;
}
ostream &operator<<(ostream &out, const RealEstate &r)
{
out << "Price: " << r.price << endl;
out << "Bedroom: " << r.bedroomNumb << endl;
out << "Baths: " << r.bathsNumb << endl;
return out;
}
int main()
{
}
From what I understand you would like to have a few try and catches in your main(), and throws in the functions that are accepting user input. If that is the case, you should definitely make use of the throw keyword within your functions. In your main, you would
int main(){
try{
function() //note that the function you are calling here should throw an error of type char* and throw this error if the number input by the user is negative and non-numeric.
}catch(const char* msg)
}
That is a brief explanation of how you would implement Error Handling (given the program and information you have provided).
Hope this helps!

How do I go about printing a vector of objects?

I'm guessing I might have to use pointers, but haven't gone in depth too much on them in class yet to try and implement them in my program. I have this so far, the printing function is towards the middle of the program. I'm not quite sure on how to print out the elements from the vector as my approach didn't work.
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class rolodex
{
string name;
string street, town, state;
string zip;
string phone;
vector <rolodex> entries;
public:
rolodex();
void getmenu();
void add_entry();
void set_name();
void set_address();
void set_phone();
void printinfo();
};
rolodex :: rolodex() : name(""), street(""), town(""), state(""), zip(""),
phone(""), entries()
{
}
void rolodex :: getmenu()
{
cout << "\n\n1)Add Entry";
cout << "\n5)Print All Entries";
cout << "\n6)Exit" << endl;
}
void rolodex :: add_entry()
{
rolodex temp;
cout << "\n\nEnter Name: ";
temp.set_name();
temp.set_address();
cout << "\n\nEnter Your Phone Number: ";
temp.set_phone();
entries.push_back(temp);
}
void rolodex :: set_name()
{
cin.ignore();
getline(cin, name);
}
void rolodex :: set_address()
{
cout << "\n\nNow we'll enter address information.";
cout << "\n\nStreet: ";
getline(cin, street);
cout << "\n\nTown: ";
getline(cin, town);
cout << "\n\nState: ";
getline(cin, state);
cout << "\n\nZip: ";
getline(cin, zip);
}
void rolodex :: set_phone()
{
getline(cin, phone);
}
void rolodex :: printinfo()
{
for(unsigned int i = 0; i < entries.size(); i++)
{
cout << entries[i] << endl; //This is where I'm stuck since I've only
//worked with vectors of non-object data
//type
}
}
int main()
{
rolodex person, menu;
short choice;
bool done = false;
do
{
menu.getmenu();
cout << "\n\nEnter a choice: ";
cin >> choice;
switch(choice)
{
case 1:
person.add_entry();
break;
case 5:
person.printinfo();
break;
case 6:
done = true;
break;
default:
cout << "\n\nInvalid Entry." << endl << endl;
}
} while(!done && isdigit(choice));
return 0;
}
πάντα ῥεῖ is right, but to add a little more detail...
You need to specify how you want the stream to handle your object. This is done by by adding a << operator. For example:
std::ostream& operator<<(std::ostream& s, const rolodex& r){
// Or however you want to format it.
s << "Name: " << r.name << " : ";
s << "Street: " << r.street << " : ";
s << "Town: " << r.town << " : ";
s << "State: " << r.state << " : ";
s << "Zip: " << r.zip << "\n";
}
Unfortunately, the function above tries to access the private fields of your class, which it can't because it is not part of the class definition.
An easy way to address that is to declare this function a "friend" inside of the class definition, like such:
friend std::ostream& operator<<(std::ostream&, const rolodex&);
...And since you might appreciate it, one big copy-pasteable chunk that you can use directly that should make your function work:
class rolodex
{
string name;
string street, town, state;
string zip;
string phone;
vector <rolodex> entries;
public:
rolodex();
void getmenu();
void add_entry();
void set_name();
void set_address();
void set_phone();
void printinfo();
friend std::ostream& operator<<(std::ostream&, const rolodex&);
};
std::ostream& operator<<(std::ostream& s, const rolodex& r){
// Or however you want to format it.
s << "Name: " << r.name << " : ";
s << "Street: " << r.street << " : ";
s << "Town: " << r.town << " : ";
s << "State: " << r.state << " : ";
s << "Zip: " << r.zip << "\n";
}
Following up on πάντα ῥεῖ's suggestion, here's one way of doing that, changing your design as little as possible:
1) Create a non-member overloaded operator<< for your rolodex class:
std::ostream& operator<< (std::ostream& os, const rolodex& rol)
{
os << rol.name << ":" << std::endl
<< "\t" << rol.street << std::endl
<< "\t" << rol.town << std::endl
<< "\t" << rol.state << std::endl
<< "\t" << rol.zip << std::endl
<< "\t" << rol.phone << std::endl;
return os;
}
.. but the compiler will chide you for attempting to access private members (by default, members are private) from outside the class, so you would have to relax the rules a bit:
class rolodex
{
...
public:
...
friend std::ostream& operator<< (std::ostream& os, const rolodex& rol);
};
You can't have the operator<< inside the class itself, see does-overloading-operator-works-inside-the-class.
However, it is almost always better design to add getter functions to your public interface anyway. You would have get_name() etc in the public: section of your class def, those functions would initially just return the values of the private member variables, and then your operator<< can use them instead of trying to access the private members. You then no longer require the friend declaration.
I upvoted Some programmer dude's remark about your design
The code for letting the use input the data really shouldn't be inside the rolodex class, because it makes the class hard to reuse. Image wanting to re-use the rolodex from a graphical interface, for example, and it's not such a good idea to have the rolodex contain instances of itself inside the vector.
I would suggest a
1) Person class containing all the person's attributes, with public getters get_name() and setters set_name() that don't use a specific entry method, just take the data as arguments e.g. set_name(std::string& name).
2) an non-member operator<< to output a person to an output stream
3) a Rolodex class with a private std::vector<Person> and methods to add a person, write all the persons to an output stream, etc..
Good luck & enjoy :-)
Edit: the menu structure on the terminal should IMHO be left inside the main() function or encapsulated into another class. But certainly don't leave it in Rolodex or worse, Person.

Error when overloading opertor>> for string memebrs in the class

When I input the value for the string types, for examples:
_ho I typed Peter
_hoten I typed Peter Parker
_ten I typed Marry
My output on the screen was:
Peter Peter Marry
Here is my code:
class SinhVien
{
private:
string _ho;
string _tenlot;
string _ten;
public:
static int InstanceCount;
SinhVien();
string ToString() const;
friend istream& operator>>(istream& in, SinhVien* p);
friend ostream& operator<<(ostream& out, const SinhVien* p);
~SinhVien();
};
istream& operator>>(istream& in, SinhVien *p)
{
cout << "Nhap ho: \n";
in >> p->_ho;
rewind(stdin);
cout << "Nhap ten lot: \n";
in >> p->_tenlot;
rewind(stdin);
cout << "Nhap ten: \n";
in >> p->_ten;
return in;
}
string SinhVien::ToString() const
{
stringstream writer;
writer << _ho << " " << _tenlot << " " << _ten << "\n";
return writer.str();
}
ostream& operator<<(ostream &out, const SinhVien* p)
{
out << p->ToString();
return out;
}
void main()
{
SinhVien *a;
a = new SinhVien();
cin >> a;
cout << a;
cout << "\nTo string:\n";
cout << a->ToString();
delete a;
system("pause");
}
In your std::basic_istream::operator>> overload, you need to use std::geline() instead of std::cin >>, so that you can get complete input name with spaces.
Secondly, you should pass the reference of the object pointer, so that the change will be applied to the passed object, not to its copy.
Fix:
std::istream& operator>>(std::istream& in, SinhVien* &p)
{ // ^^ take ref of object you pass, so that the change will be applied to the object, not to the copy of it.
std::cout << "Nhap ho: \n";
std::getline(in, p->_ho); // change
std::rewind(stdin);
std::cout << "Nhap ten lot: \n";
std::getline(in, p->_tenlot); // change
std::rewind(stdin);
std::cout << "Nhap ten: \n";
std::getline(in, p->_ten); // change
return in;
}
Above will work for one single input. However, the case of multiple inputs and use of std::cin >> in the main() can cause again some input skipping problems. Thanks to #Yksisarvinen pointing this out.
You can read more in this SO post: Why does std::getline() skip input after a formatted extraction?
Side note: In modern C++, you do not need to manage the raw pointers, anymore. Because you have smart pointers which will manage your object's lifetime as it goes out of scope. So use it whenever its possible.
That means you can do something like this: SEE LIVE
#include <memory>
class SinhVien
{
private: // memebrs
public:
// other member functions
friend istream& operator>>(istream& in, const std::unique_ptr<SinhVien> &p);
friend ostream& operator<<(ostream& out, const std::unique_ptr<SinhVien> &p);
};
std::istream& operator>>(std::istream& in, const std::unique_ptr<SinhVien> &p)
{
std::cout << "Nhap ho: \n";
std::getline(in, p->_ho); // change
std::cout << "Nhap ten lot: \n";
std::getline(in, p->_tenlot); // change
std::rewind(stdin);
std::cout << "Nhap ten: \n";
std::getline(in, p->_ten); // change
return in;
}
std::ostream& operator<<(std::ostream &out, const std::unique_ptr<SinhVien> &p)
{
return out << p->ToString();
}
int main()
{
auto a = std::make_unique<SinhVien>();
std::cin >> a;
std::cout << a;
std::cout << "\nTo string:\n";
std::cout << a->ToString();
return 0;
}

C++ operator overload doesnt work

I have a question about operators and how to overload them. There is an example of code and I'm overloading operator<< but it doesn't work. There is class that I use:
class CStudent{ //class for students and their attributes
int m_id;
int m_age;
float m_studyAverage;
public:
CStudent(int initId, int initAge, float initStudyAverage): m_id(initId), m_age(initAge), m_studyAverage(initStudyAverage){}
int changeId(int newId){
m_id = newId;
return m_id;
}
int increaseAge(){
m_age++;
return m_age;
}
float changeStudyAverage(float value){
m_studyAverage += value;
return m_studyAverage;
}
void printDetails(){
cout << m_id << endl;
cout << m_age << endl;
cout << m_studyAverage << endl;
}
friend ostream operator<< (ostream stream, const CStudent student);
};
Overload:
ostream operator<< (ostream stream, const CStudent student){
stream << student.m_id << endl;
stream << student.m_age << endl;
stream << student.m_studyAverage << endl;
return stream;
}
And there is main method:
int main(){
CStudent peter(1564212,20,1.1);
CStudent carl(154624,24,2.6);
cout << "Before the change" << endl;
peter.printDetails();
cout << carl;
peter.increaseAge();
peter.changeStudyAverage(0.3);
carl.changeId(221783);
carl.changeStudyAverage(-1.1);
cout << "After the change" << endl;
peter.printDetails();
cout << carl;
return 0;
}
Where is the problem?
The problem here is you need to learn what references are and the difference between std::ostream and std::ostream& is.
std::ostream& operator<< (std::ostream& stream, const CStudent& student)

C++ Operator '<<' error

I have a question regarding a homework assignment.
I have two classes. One is called ticket.cpp, and the other is called TicketOrder.cpp
The main is within the ticket.cpp.
I am using a g++ compiler on Linux.
What I'm doing is trying to is print out a vector of a TicketOrder object called orders, but it gives me the following error:
ticket.cpp:57: error: no match for 'operator<<' in 'std::cout << orders. std::vector<_Tp, _Alloc>::operator[] with _Tp = TicketOrder, _Alloc = std::allocator'
Here is my code:
ticket.cpp
#include <iostream>
#include <vector>
#include <limits>
#include <cctype>
#include "TicketOrder.cpp"
using namespace std;
int main ()
{
int numberoftickets=0;
string input2;
char input3;
int profit=0;
vector <TicketOrder> orders;
int atotalmoney=0;
int btotalmoney=0;
int ctotalmoney=0;
int dtotalmoney=0;
int etotalmoney=0;
do
{
cout << "\nPick a ticket that you would like to buy: \n\n";
cout << "(A) Students without an activity card: $2.00 \n";
cout << "(B) Faculty and staff: $3.00 \n";
cout << "(C) USC alumni: $5.00 \n";
cout << "(D) UCLA students and alumni: $20.00 \n";
cout << "(E) Everyone else: $10.00 \n";
cin >> input3;
if (input3=='A')
{
cout << "How many tickets do you wish to buy? " <<endl;
if (numberoftickets >0)
{
TicketOrder order;
order.setQuantity(numberoftickets);
order.setType(input3);
orders.push_back(order);
for (int i=0; i< orders.size(); i++)
{
cout << orders[i];
}
}
}
else
{
cout << "Sorry did not recognize input, try again. " << endl;
}
} while (input3 != 'S');
TicketOrder.cpp:
#include <iostream>
using namespace std;
class TicketOrder
{
public :
//Getters
int getQuantity() const
{
return quantity;
}
char getType() const
{
return type;
}
//Setters
void setQuantity (int x)
{
quantity=x;
}
void setType(char y)
{
type =y;
}
private:
char type;
char quantity;
};
As the compiler is clumsily trying to explain, the code is missing an operator<< for the TicketOrder class.
class TicketOrder {
public:
friend std::ostream& operator<<(std::ostream& os, TicketOrder const& order) {
os << "Type: " << type << ", quantity: " << quantity;
return os;
}
char type;
int quantity;
};
(Note: you probably want to change quantity to int.)
You must add the operator << function as a friend to be able to print values from your TicketOrder objects with cout. Further reading
You're attempting to use the << operator on cout and a TicketOrder object. That is undefined. You should use the TicketOrder object to generate a string first, then output that via cout. Either that, or you can define the << operator for the TicketOrder class, as described in one of the other two answers.