I have got a question -
Write a c++ program to calculate Gross salary(net salary+DA+TDS) for 4 employees where overload the + operator for getting the total salary obtained by all the 4 employees. Also get the average salary of employees by operator overloading. display all the details of all four employees. Also display who is getting highest salary. Employee salary must be entered by the user at runtime.
#include<iostream>
#include<string>
using namespace std;
class Employee
{
private:
int net_salary, DA, TDA, Gross_salary;
public:
void SetData(int net, int da, int tda, int gross)
{
net_salary=net;
DA=da;
TDA=tda;
Gross_salary=gross;
}
void GetData()
{
cout << "Enter net salary: "<<net_salary;
DA = (15*net_salary)/100; //Declaring the value of DA as 15% and calculating the amount
//on basis of net salary of the employee
TDA = (10*net_salary)/100; //Declaring the value of TDA as 10% and calculating the amount
// of TDA on basis of net salary
Gross_salary = net_salary+DA+TDA;
}
void DisplayData()
{
cout << "Total Gross Salary = "<<Gross_salary;
}
Employee operator +(Employee e)
{
Employee temp;
temp.Gross_salary=Gross_salary+e.Gross_salary;
return temp;
}
};
int main()
{
Employee e1,e2,e3,e4,e5;
e1.GetData();
e2.GetData();
e3.GetData();
e4.GetData();
e5=e1+e2+e3+e4;
e5.DisplayData();
return 0;
}
The trouble comes from the absent initial values for the data members.
// ...
cout << "Enter net salary: " << net_salary;
DA = (15*net_salary)/100;
// ...
Here, in the GetData() member function, that is called after you have created five default initialized objects e1,e2,e3,e4,e5 of Employee type. The net_salary here is of built-in type and is default initialized by the implicitly defined default constructor, hence it has an undefined value. Then you assign this undefined value to the DA and so on in the body of the GetData().
You should not look toward the SetData() as a solution for this, since it should act as a setter method, a method used to modify an already initialized object. You will need to implement constructor(s) for your class, or you can at least supply in-class initializers for the members, like so:
// ...
int net_salary=0, DA=0, TDA=0, Gross_salary=0;
// ...
I can't help but notice that GetData() either has a confusing name or tries to do more than it is intended to do. It does some internal computation, which is ok for a GetSomething function, but it modifies internal data while does some prints.
Also, note the line (in the GetData()):
Enter net salary:
Will be followed by an output, you won't be given a chance to input any data in the GetData(). I assume, you may want to create a constructor that takes input from a user, and then call a function to do all the needed computations.
Related
I'm building my first program in C++ and I'm stuck where I'm trying to print the value of fee multiple times using for loop after giving value once. By running the loop it is giving garbage value every time after giving right value at first time. I'm new to the class topic in C++. Please tell me how can I print the same value of private variable fee every time the loop runs.
#include<iostream>
using namespace std;
class FEE
{
private:
int fee;
public:
void setfee()
{
cout<<"Enter the monthly fee= ";
cin>>fee;
}
void showfee()
{
cout<<"Monthly fee is "<<fee<<endl;
}
};
int main()
{
FEE stu[5];
for(int i=0;i<5;i++)
{
if(i==0)
stu[i].setfee();
stu[i].showfee();
}
}
The problem is that you're calling the setfee member function only for the first object in the array stu. And since the array stu was default initialized meaning its elements were also default initialized, the data member fee of each of those elements inside stu has an indeterminate value. So, calling showfee on the elements on which setfee was not called, is undefined behavior since for those elements fee has indeterminate value and you're printing the value inside showfee.
because I want to set the same fee amount for every student and then autoprint it in a file for every stu[] array variable.
To solve this and do what you said in the above quoted statement, you can ask the user for the fee inside the main and then pass the input as an argument to the setfee member function. For this we have to change setfee member function in such a way that it has an int parameter. Next, using a 2nd for loop we could print the fee of each of the elements inside stu using showfee member function. This is shown below:
#include<iostream>
class FEE
{
private:
int fee = 0; //use in-class initializer for built in type
public:
void setfee(int pfee)
{
fee = pfee;
}
void showfee()
{
std::cout<<"Monthly fee is "<<fee<<std::endl;
}
};
int main()
{
FEE stu[5]; //default initiailized array
int inputFee = 0;
for(int i=0;i<5;i++)
{
std::cout<<"Enter the monthly fee= ";
std::cin>>inputFee;
//call setfee passing the inputFee
stu[i].setfee(inputFee);
}
for(int i = 0; i<5; ++i)
{
stu[i].showfee();
}
}
Demo
Also, note that using a std::vector instead of built in array is also an option here.
Some of the changes that i made include:
Added a parameter to the setfee member function.
Used in-class initializer for the fee data member.
The input fee is taken inside main which is then passed to the setfee member function for each of the element inside stu.
The member function showfee is called for each of the element inside stu using the 2nd for loop.
This is my first question on here, so excuse me if I've formatted everything in a wrong way.
So, to get to the problem - this is s university assignment of mine. The goal is to create a class called Student, which has a few fields, and store the instances in an array of Student objects. One of the tasks is to have a static variable inside the class that keeps track of how many Student instances have been created. To clarify, I have a getData() method that asks the user for the values, and then sets the current object's values to those entered (basically just like a constructor, which makes the constructors obsolete, but they want us to do it that way for some reason). In the getData() function, the static count variable gets raised by 1, as well as in the constructors, and gets decremented in the destructor.
The issue is that for some reason, Student::amount variable sets itself to 100. Every time that i try to access it from the main() function, its 100 plus the amount of students created, so if we have created 2 students, Student::amount will be equal to 102. I've nowhere explicitly set it to that number, which also matches the size of the array, by the way.
I'm still rather new to C++, I've read and watched some material on how OOP works here, but I've barely even scratched the surface.
Sorry again if my question is badly formulated or/and badly formatted, and I hope you can help me with this!
#include <iostream>
#include <string>
using namespace std;
class Date {
...
};
class Student {
// Fields
private:
string name = "";
string PID = "";
int marks[5]{ 0 };
short course = 0;
public:
// Count of all students
static int amount;
// Getters
...
// Setters
...
// Constructors
Student(); // Default one, Student::amount gets raised by 1 there
Student(string name, string PID, int marks[5], short course);
// Destructor
~Student();
// Methods
void getData();
void display(); // Display the information of a student
};
// Array of students
Student students[100];
// Student::Count
int Student::amount; // Initializes with 0 if not explicitly initialized
void Student::getData() {
cin.ignore();
cout << "\nName: "; getline(cin, name);
cout << "PID: "; getline(cin, PID);
cout << "Marks:\n";
for (int i = 0; i < 5; i++)
{
cin >> marks[i];
}
cout << "Course: "; cin >> course;
Student::amount++;
}
Student::Student(string name, string PID, int marks[5], short course) {
this->setName(name);
this->setPID(PID);
this->setMarks(marks);
this->setCourse(course);
Student::amount++;
}
The global declaration Student students[100]; calls the default Student constructor 100 times, before main is reached. According to your comment (you don't supply the constructor implementation), that constructor increases amount by 1.
A solution here is to remove Student::amount and instead use
std::vector<Student> students;
students.size() will give you the number of students in that container. Use push_back to put students into the vector.
A very crude alternative that at least is broadly compliant with the question constraints is to remove the amount increment from the default constructor, and all other places apart from the four argument constructor.
Apologies in advance if this is below the community's paygrade. I just started learning about OOP and English is not my native language.
I just learned about using getters and setters, and the importance of data encapsulation. However, All the examples I've seen online using getters and setters all deal with static values such as the one below:
#include <iostream>
using namespace std;
class Employee {
private:
// Private attribute
int salary;
public:
// Setter
void setSalary(int s) {
salary = s;
}
// Getter
int getSalary() {
return salary;
}
};
int main() {
Employee myObj;
myObj.setSalary(50000);
cout << myObj.getSalary();
return 0;
}
I've managed to allow user input by declaring another set of variables and feeding them as parameters into the setters like below:
int main() {
Employee myObj;
int salary;
cout<<"Enter salary: " << endl;
cin>>salary;
myObj.setSalary(salary);
cout << myObj.getSalary();
return 0;
}
Is this the only way to allow user input? Is there a more elegant way of accomplishing this other than declaring another set of local variables?
Sorry if this is a beginner question. I'm new to the C++ game and am still getting my feet wet.
Is this the only way to allow user input? Is there a more elegant way of accomplishing this other than declaring another set of local variables?
(and from comment)
I was hoping I could do some variation of myObj.setSalary(cin) so cin would feed the value directly into the getter without me having to pass it into temp variables
I would not mix input from stdin with setters, better keep them as seperate methods:
class foo {
int x;
int other_member;
public:
void set_x(int a) { x = a; }
void set_other_member(int a) { other_member = a; }
void read_x(std::istream& in) {
in >> x;
}
};
This lets you write
f.read_x(std::cin);
to read x from stdin.
Note that there are many ways to accomplish the same and what is "elegant" is rather subjective. Typically you would provide an overload for operator>> to read a foo from a stream:
std::istream& operator>>(std::istream& in, foo& f) {
int a,b;
in >> a >> b;
f.set_x(a);
f.set_other_member(b);
}
Either this (using the setters) or you make the operator a friend of foo (to access privates directly) or you use foo::read_x to implement it. Then you can write
foo f;
std::cin >> f;
Note that C++ is not a "pure" OOP language, and idiomatic C++ will happily eschew certain OOP principles in favor of simpler and more effective code where applicable.
It is perfectly acceptable, if you want a datatype to just "hold" data, to use a plain old struct (with public data fields). Don't confuse the benefits of encapsulation (...of non-trivial constructs, so you can change their implementation internally) with any kind of "security". Getters/Setters or not, anyone can change your object's data if he wants to. Incidentially, this makes reading data easier.
cin >> e.salary;
If you don't want "just a struct", it is good style to have a constructor that sets meaningful initial values, so that you don't have "uninitialized" Employee objects flying around (RAII). This means that neither your client nor your destructor has to deal with the possibility that Employee might not actually be one (hold null pointers, or other kinds of uninitialized resources).
Employee e( "Mark Smith", 10000 );
Once you are at that point, Employee should be responsible for anything that happens to / with an Employee object. That implies that it should not be somebody else that's reading user input and writes it to Employee data fields (via setters or not), it should be a message sent to the Employee object that it should update its fields, from input or otherwise, as appropriate.
(Consider the possibility of someone setting a pointer member of yours to nullptr, or worse, some random value. Your destructor would throw a fit trying to free the resource, and then how you'd debug where that invalid pointer came from?)
At which point we arrive at the operator>>(), which can be overloaded for istreams and your class.
class Employee
{
public:
// ...
friend istream & operator>>( istream &, Employee & );
// ...
};
istream & operator>>( istream & in, Employee & e )
{
getline( e.name, in );
in >> e.salary;
return in;
}
int main()
{
Employee e; // For the sake of example, a default constructed employee
cout << "Enter new employee's name (on its own line), and salary:\n";
cin >> e;
}
And once there, you get an idea of what data encapsulation actually means: Employee is an object, not a data container. You should not poke around in it's innards, you should send messages.
Employee e( "Mark Smith", Role::INTERNEE, 10000 );
cout << e; // Output: "Mark Smith, Internee, with an income of 10.000 sicles."
e.promote( Role::TEAM_LEAD, 10000 ); // Exception: "Wrong pay scale for Team Leads."
e.promote( Role::TEAM_LEAD, 30000 );
cout << e; // Output: "Mark Smith, Team Lead, with an income of 30.000 sicles and a free car."
Note how the Employee class sanity-checked the new salary, and knew that a promotion to Team Lead automatically included a free car, and did that without you having to set that yourself. That is what this encapsulation is about...
As for your question "as asked", whether your implementation could do read a salary more elegantly, you could of course...
void setSalary(istream & in) {
in >> salary;
}
...and...
cout << "Enter salary:" << endl;
e.setSalary( cin );
And because that's properly encapsuled, you could add sanity checks, change the type of salary to BigNum, or start support reading in hieratic.
THIS QUESTION IS A GENERAL ANSWER WILL COVER YOU QUESTION
So in OOP, making and using only the copy or the OBJECT is a core concept, the way you are making a single copy OBJECT of a class is a standard one, but have you ever thought about MAKING AN ARRAY OF TYPE "YOUR CLASS's Objects"? because in your case the obj will only hold only one copy of Employee but if you use a data structure e.g "Array" for storing a number of objects then it will be a lot easier let me clarify for you
EXAMPLE
int a, b, c, d, e, f, g ... z;
assigning all of these alphabets a value will be a huge pain but wait you can have a data structure for it.
int arrayOfAlphabets[26];
now you want to assign values? (you can assign it dynamically but this is just an example to show you that you can just control the assigning of a variable with just a counter)
for(int x = 0 ; x < 26; x++){
arryOfAlphabets[x] = someNumber
}
Want to get Values? you can get values dynamically but this is just an example to show you that you can just control the setting & getting of a variable with just a counter)
for(int x = 0; x < 26; x++){
cout << "Value of Alphabet" + x + " is: " + arrayOfAlphabets[x] << endl;
}
now you have seen the example that making a data structure specific data type can remove a lot of pain of yours now keep in mind for the sake of understanding,
YOUR CLASS IS DATATYPE THAT YOU CREATED
class Employee {
private:
// Private attribute
int salary;
public:
// Setter
void setSalary(int s) {
salary = s;
}
// Getter
int getSalary() {
return salary;
}
};
and in main what you can do is
int main(){
Employee emp[5];
int tempSalery;
for( int i=0; i<5; i++ )
{
cin >> tempSalery;
emp[i].setSalery(tempSalery);
}
}
now to print out your result
for( int i=0; i<5; i++ ){
cout << "Employee " + x + "Salery is: " + emp[i].getSalery() << endl;
}
I've to design a ticket booking system for a cinema, which has 50 seats only (5 rows with 10 seats each)
I've been given the Cinema class below, and this should not be modified
class Cinema{
private:
Ticket ticket[50]; // not sure what it is going on
public:
Cinema(); //constructor
double purchaseTicket(int); // ticket ID as parameter, check if it is available, if so update it as unavailable. If not, return 0.
void listAll();
};
And this is the Ticket class
class Ticket{
private:
int ID[50]; //ticket ID (correct to store data in array?)
int price; // ticket price
// have to provide set and get function for ID and price, have no idea even I've googled on this topic
bool available[50]; // availability of ticket
public:
Ticket(); //constructor
bool status(int); // return availability of ticket
void setAvailable(int); //update status of ticket as available
void buy(int); //update status of ticket as unavailable
};
This is the main function (given) which simulates the purchase ticket function
int main(){
Cinema myCinema;
myCinema.listAll(); // available seats print "O", otherwise print "X"
//simulate to purchse ticket 15, 16, 17
double price = 0;
price += myCinema.purchaseTicket(15);
price += myCinema.purchaseTicket(16);
price += myCinema.purchaseTicket(17);
cout <<"\nTotal Price: $" << price << endl << endl;
//print the current status
myCinema.listAll();
return 0;
}
can anyone tell me how to use "Ticket ticket[50];" ? this troubles me a lot and many steps cannot be finished
and tell me also if there are any problems in the Ticket class
Each seat has a ticket. Therefore there are fifty tickets to purchase. It's a slightly strange way of looking at things but I think you can think of 'ticket' as synonymous with 'seat'.
Your ticket class is wrong. Remember a ticket object represents an individual ticket (which stands for an individual seat). Therefore one ticket has one id, and one availability. Therefore the arrays in the ticket class are wrong.
class Ticket{
private:
int ID; //ticket ID
int price; // ticket price
bool available; // availability of ticket
public:
...
};
The setters and getters are trivial
int Ticket::getPrice() const { return price; }
void Ticket::setPrice(int p) { price = p; }
Similar for availability.
Just noticed that Cinema::purchaseTicket returns a double, why I have no idea.
You cannot use ticket array directly, since it is a private member of Cinema. You can only access it using the purchase function mentioned in the class. Since that class should not be modified, this is the only way.
(Note: int array for ID member is wrong, use only int).
However, if you were to modify that class to make Ticket ticket[50] as public,
An example on how to use it is as follows:
myCinema.ticket[0].ID to access the first ticket's ID ( preferably use char array to store ticket ID, else just int: int array is wrong)
access the members u want through the dot operator.
#include<iostream>
#include <string>
using namespace std;
class Car{
private:
public: Car(int, string, int);
Car(){} //default constructor
void setbrake();
void setacc();
int year,speed;
string make;
};
Car::Car(int year, string make, int speed = 0) //constructor with parameters
{
cout << "Enter your car's year." << endl;
cin >> year;
cout << "Enter your car's make. " << endl;
cin >> make;
cin.ignore();
speed = 0; }
void Car::setbrake(){ //first function
speed = speed - 5;
cout << "Your " << make << " is traveling at " << speed;
cout << " MPH.";}
void Car::setacc(){ //second function
speed = speed + 5;
cout << "Your " << make << " is traveling at " << speed;
cout << " MPH.";}
int main()
{
Car car1(0,"s");
cout << car1.make;
cout << car1.speed;
cout << car1.year;
car1.setacc();
system("pause");
return 0;
}
I'm having a problem getting my variables to display in my two member functions, and it doesn't display anything in main.
The speed variable always comes out to 49898575 <-- some randomly high number like that, and I assume I initialized it to 0.
I've been stuck on this all week.
How do I connect my class private variables and my member functions.
I thought my constructor with parameters would take care of that problem, but obviously not.
Can someone please take the time to critique this code for me. I'm going to pull my hair out.
Here's the problem that was assigned for class, and this is what I'm aiming to do, but I'm not catching on to classes and member functions, and how they work together.
Write a class named Car that has the following member variables:
• year. An int that holds the car’s model year.
• make. A string that holds the make of the car.
• speed. An int that holds the car’s current speed.
In addition, the class should have the following member functions.
• Constructor. The constructor should accept the car’s year and make as arguments
and assign these values to the object’s year and make member variables. The constructor
should initialize the speed member variable to 0.
• Accessors. Appropriate accessor functions should be created to allow values to be
retrieved from an object’s year, make, and speed member variables.
• accelerate. The accelerate function should add 5 to the speed member variable
each time it is called.
• brake. The brake function should subtract 5 from the speed member variable each
time it is called.
Demonstrate the class in a program that creates a Car object, and then calls the accelerate
function five times. After each call to the accelerate function, get the current speed of the car and display it.
Then, call the brake function five times.
After each call to the brake
function, get the current speed of the car and display it.
You're changing the values of your parameters, which shadow your members, leaving both ints uninitialized (the string will be an empty string).
The better option is to use different names:
Car::Car(int y, string m, int s = 0)
You could, however, use this:
this->speed = 0;
I'd recommend a constructor initializer list, though, which doesn't require either, and doing it in the order they're declared in the class:
Car::Car(int year, string make, int speed = 0)
: year(year), speed(speed), make(make) {}
Ideally, I would do something like this, with tweaking depending on what else it's meant to be used for (I'll keep it C++03):
class Car {
int year_;
std::string make_;
int speed_;
public:
Car(int, const std::string &, int);
void brake();
void accelerate();
void printInfo() const;
};
Car::Car(int year, const std::string &make)
: year_(year), make_(make), speed_() {} //speed should always be 0
void Car::brake() {
speed_ -= 5; //consider ensuring it stays at or above 0
}
void Car::accelerate() {
speed_ += 5;
}
void Car::printInfo() const {
std::cout << "Your " << make_ << " is traveling at " << speed_ << " MPH.";
}
You'll have to figure out exactly what the default constructor should do if you want one. I used a constructor initializer list to initialize the data members, I separated the printing from the accelerating/braking, accepted const references where reasonable, and made the printing function const since it doesn't modify the object.