So I am trying to read in a file using private class variables. I am unsure how to display the file. There might be another way to do this, but this is what I could think of. Note, its my first project using classes and private and public/private members. Was I on the right path atleast? I keep getting an error for the int main function. How can I fix it?
This is my main:
#include "Record.h"
#include <sstream>
int main ()
{
Record employee;
ifstream myFile;
myFile.open("Project 3.dat");
string str;
int i=0;
if (myFile.is_open())
{
while (getline(myFile, str))
{
istringstream ss(str);
ss >> employee.get_name(str) >> employee.get_id(stoi(str)) >>
employee.get_rate(stoi(str)) >> employee.get_hoursWorked(stoi(str));
}
}
return 0;
}
This is my header:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
class Record
{
private:
string name;
int id;
double rate;
double hours;
public:
Record();
Record (string n, int empid, double hourlyRate, double hoursWorked);
// constructor
void read_data_from_file();
double calculate_wage();
void print_data();
/* ASETTERS AND GETTERS */
void set_name (string n);
string get_name();
void set_id (int empid);
int get_id();
void set_rate (double hourlyRate);
double get_rate();
void set_hoursWorked(double hoursWorked);
double get_hoursWorked();
/* END OF SETTERS AND GETTERS */
};
This is my cpp
#include "Record.h"
Record::Record():name(), id(0), rate(0), hours(0) {} //default constructor
must be implemented first
Record::Record(string n, int empid, double hourlyRate, double hoursWorked)
{
name = n;
empid = id;
hourlyRate = rate;
hoursWorked = hours;
}
//
void Record::set_name(string n)
{
name = n;
}
string Record::get_name()
{
return name;
}
//
void Record::set_id(int empid)
{
id = empid;
}
int Record::get_id()
{
return id;
}
//
void Record::set_rate(double hourlyRate)
{
rate = hourlyRate;
}
double Record::get_rate()
{
return rate;
}
//
void Record::set_hoursWorked(double hoursWorked)
{
hours = hoursWorked;
}
double Record::get_hoursWorked()
{
return hours;
}
//
double Record::calculate_wage()
{
return (rate * hours);
}
There are some issues with your code that I can see. most of your problems aren't related to your question (I mean using a class or private/public members). you have more basic misunderstandings. So here's some explanation that might help you:
1- Using functions : You have some troubles using your defined functions, A function can have multiple input parameters and one return value. basically it's like this return_type function_name(parameter_type param1, ...). it means that if you call this function you need to pass param1,... and expect your function operation and then have a return value of return_type. You defined some set and get functions. if you want to set something you should call set function and pass your desired value to it and it will copy your value to your defined member data, after that you can call get function to retrieve that value. So when you call get function with parameter it will raise error. Here you want to call set function.
2- Using stoi : As you can see you are getting error on using stoi function too, this is a function for converting string to integer, The thing that you missed here is that this function declared in std namespace. If you want to use it you need to use it like this std::stoi(str). one other thing, using namespace std is a bad practice.
3- Design matters : In OOP design, a class must have a purpose and an actual job to do. It might be an interface to abstract class but a bunch of set and get functions will not fulfill the need to create a class. Here if your class is going to do file operations, it's OK, but as far as you shared your code it's just some set and get functions.
Related
I am new to this. Basically I just learnt how to use class in C++. When I try to print out, the values just seem to be 0. Can anyone help me out? Its supposed to print out:
Susan Myers 47899 Accounting Vice President
Mark Jones 39119 IT Position
Joy Rogers 81774 Manufacturing Engineer
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
class Employee
{
private:
string name;
int idNumber;
string department;
string position;
public:
Employee()
{
name=" ";
idNumber=0;
department=" ";
position=" ";
}
Employee(string, int, string, string)
{
int id;
string n,d,p;
name=n;
idNumber=id;
department=d;
position=p;
}
Employee(string, int)
{
string n;
int id;
name=n;
idNumber=id;
}
void setName(string)
{
string n;
name=n;
}
void setId(int)
{
int id;
idNumber=id;
}
void setDepartment(string)
{
string d;
department=d;
}
void setPosition(string)
{
string p;
position=p;
}
string getName() const
{
return name;
}
int getId() const
{
return idNumber;
}
string getDepartment() const
{
return department;
}
string getPosition() const
{
return position;
}
};
int main()
{
Employee e1;
Employee e2;
Employee e3;
e1.setName("Susan Meyers");
e2.setName("Mark Jones");
e3.setName("Joy Rogers");
e1.setId(47899);
e2.setId(39119);
e3.setId(81744);
e1.setDepartment("Accounting");
e2.setDepartment("IT");
e3.setDepartment("Manufacturing");
e1.setPosition("Vice President");
e2.setPosition("Programmer");
e3.setPosition("Engineer");
cout<<"---------------------------------------"<<endl;
cout<<"Name"<<setw(6)<<"ID Number"<<setw(10)<<"Department"<<setw(12)<<"Position"<<endl;
cout<<e1.getName()<<setw(6)<<e1.getId()<<setw(10)<<e1.getDepartment()<<setw(12)<<e1.getDepartment()<<endl;
cout<<e2.getName()<<setw(6)<<e2.getId()<<setw(10)<<e2.getDepartment()<<setw(12)<<e2.getDepartment()<<endl;
cout<<e3.getName()<<setw(6)<<e3.getId()<<setw(10)<<e3.getDepartment()<<setw(12)<<e3.getDepartment()<<endl;
return 0;
}
This is what you get when you rely on guesswork rather than properly reading an introductory textbook on C++
A constructor of the Employee class which (apart from a blank line that I've removed) you define as
Employee(string, int, string, string)
{
int id;
string n,d,p;
name=n;
idNumber=id;
department=d;
position=p;
}
has the following effects.
The four arguments passed by the caller are ignored, since they are not named.
Four default-initialised variables (id, n, d, and p) are defined local to the constructor body. id will be uninitialised. The others, since they are std::string, are default-initialised (to an empty string)
The next four statements copy those variables into class members. The result is that initialising idNumber has undefined behaviour (since id is uninitialised) and the three strings are initialised to empty strings.
To get the effect that (I assume) you intend, change this to;
Employee(std::string n, int id, std::string d, std::string p)
{
name=n;
idNumber=id;
department=d;
position=p;
}
Note that I'm calling string by its full name std::string. That allows removing the using namespace std which (among other things) is BAD practice in header files.
Even better, change this to
Employee(const std::string &n, int id, const std::string &d, const std::string &p) :
name(n), idNumber(id), department(d), position(p)
{
}
which passes the strings by const reference (avoids additional copies of std::strings) and uses an initialiser list instead of assigning to members in the constructor.
Similar comments apply to ALL of the member functions of Employee, except that only constructors can have initialiser lists.
Errors made
Presentation
Your code is extremely cluttered, and has much irrelevant stuff.
Syntax
void setPosition(string){
Here your function has no argument! What is string?
Code
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
class Employee{
public:
string name;
int idNumber;
string department;
string position;
void setName(string n){
name=n;
}
void setId(int k){
int id;
idNumber=id;
}
void setDepartment(string d){
department=d;
}
void setPosition(string p){
position=p;
}
string getName(){
return name;
}
int getId(){
return idNumber;
}
string getDepartment(){
return department;
}
string getPosition(){
return position;
}
};
int main(){
Employee e1;
Employee e2;
Employee e3;
e1.setName("Susan Meyers");
e2.setName("Mark Jones");
e3.setName("Joy Rogers");
e1.setId(47899);
e2.setId(39119);
e3.setId(81744);
e1.setDepartment("Accounting");
e2.setDepartment("IT");
e3.setDepartment("Manufacturing");
e1.setPosition("Vice President");
e2.setPosition("Programmer");
e3.setPosition("Engineer");
cout<<"---------------------------------------"<<endl;
cout<<"Name"<<" "<<"ID Number"<<" "<<"Department"<<" "<<"Position"<<endl;
cout<<e1.getName()<<" "<<e1.getId()<<" "<<e1.getDepartment()<<" "<<e1.getPosition()<<endl;
cout<<e2.getName()<<" "<<e2.getId()<<" "<<e2.getDepartment()<<" "<<e2.getPosition()<<endl;
cout<<e3.getName()<<" "<<e3.getId()<<" "<<e3.getDepartment()<<" "<<e3.getPosition()<<endl;
}
Output
---------------------------------------
Name ID Number Department Position
Susan Meyers 32767 Accounting Vice President
Mark Jones 32767 IT Programmer
Joy Rogers 32767 Manufacturing Engineer
Explanation
I have shortened your code by 50%(shows how much redundant stuff you had), and here is a working code.
void setDepartment(string d){
department=d;
}
Here, string d is defined IN the function as an argument. Note that your code also cout<< department twice, and I have corrected that for you in my above code.
Hope this helps.
I'm currently defining a few properties for a class in C++ but I'm running into trouble when using type string as opposed to something like int or double. For example:
private:
int LOT;
public:
int getLOT() {
return LOT;
}
void setLOT(int value) {
LOT = value;
}
works fine, but:
private:
string name;
public:
string getName() {
return name;
}
void setName(string value) {
name = value;
}
throws these errors:
https://s26.postimg.org/wm5y7922h/error.png
The file (a header) looks something like this:
#include "general.h" // a header which includes all my other #includes
// which, yes, does include <string>
class MyClass
{
private:
string name;
public:
string getName() {
return name;
}
void setName(string value) {
name = value;
}
// other properties similar to the above
}
The purpose is to access the variable like this:
cout << "Enter your name: ";
cin >> MyClass.setName();
cout << "\nHello, " << MyClass.getName();
// although this isn't exactly how it'll be used in-program
If anyone could provide help with what I'm doing wrong or a better way to go about a string property (as, like I mentioned before, other types work fine) it would be greatly appreciated. Thanks.
string is part of std namespace.
You must use std::string instead of string or add using namespace std; (what I would not recommend you to do in your header file, read "using namespace" in c++ headers).
Here is my code:
#include <iostream>
#include <string>
using namespace std;
class Sport{
protected:
string name;
double hours;
virtual double returnCalories()=0;
public:
Sport():name("Not defined"),hours(0.0){}
Sport(string n, double c):name(n),hours(c){}
virtual ~Sport(){}
void setName(string x){
name=x;
}
void setTime(double x){
hours=x;
}
};
class Running:public Sport{
public:
static const int CALORIES = 950;
Running(){}
~Running(){}
double returnCalories(){
return hours*CALORIES;
}
};
class Activity{
public:
Sport* one;
Activity(){}
Activity(string n,double time){
one->setName(n);
one->setTime(time);
}
~Activity(){}
};
class Diary{
private:
Activity list_activity[10];
int counter_activity;
public:
Diary():counter_activity(0){}
~Diary(){}
void addActivity(Activity x){
// add activities
}
double sumCalories(){
for(int i=0;i<10;i++){
if(list_activity[i].one->getName()=="Running"){
// I want to call returnCalories() of class Running
}
}
}
};
int main() {
Activity test("Running",3.2);
Diary test2;
test2.addActivity(test);
return 0;
}
Now I have a question:
How is it possible to call returnCalories() of class Running where I want to ? ( it's commented in the code )
Is this even possible, or should I change my logic somehow ?
It's crashing because you have not initialized Sport *one; and you're attempting to call methods on a null pointer. You need to first create a Running object within the Activity constructor using the "new" operator like so:
one = new Running(n, time);
Create an overloaded constructor in your "Running" class that takes the appropriate arguments as well, so that you can initialize your variable as shown above.
I am having a hard time getting my head around how to correctly perform composition between C++ classes. Here is an example of where I'm getting stuck:
#include <iostream>
using namespace std;
class Super
{
private:
int idNum;
string Name;
public:
Super(int, string);
void setSuper();
};
Super::Super(const int id, const string superName)
{
idNum = id;
Name = superName;
}
class Sidekick
{
private:
int sideIdNum;
string sideName;
Super hero;
public:
Sidekick(int, string, Super);
void setSidekick();
};
int main()
{
Super sm;
Sidekick sk;
sm.setSuper();
sk.setSidekick();
return 0;
}
void Super::setSuper()
{
int superID;
string sname;
cin >> superID;
cin >> sname;
Super(superID, sname);
}
void Sidekick::setSidekick()
{
int id;
string siName;
Super man;
cin >> id;
cin >> siName;
//How do I perform action that automatically obtains the attributes
//from the object "hero" from Super?
}
To get attributes from Super class, you need to provide getter helpers. Below is an example:
using namespace std;
class Super
{
private:
int idNum;
string Name;
public:
Super(int, string);
void setSuper();
int getId() {return idNum;} // added here
string getName() {return Name;} // added here
};
...
void Sidekick::setSidekick()
{
int id;
string siName;
Super man;
cin >> id;
cin >> siName;
//How do I perform action that automatically obtains the attributes
//from the object "hero" from Super?
// Use yours helper here
cout << hero.getId();
cout << hero.getName();
}
By the way, you cannot calls constructors like you do before. You have, at least, two choices, either you setup the attributes at your object creation, or you provide setter helpers to perform this action.
I'm having a bit of trouble with classes used within classes, from header files.
I have a class time in time.h:
#ifndef TIME_H
#define TIME_H
#include <iostream>
using namespace std;
class Time
{
private:
int hour, minute, second;
public:
Time();
~Time();
Time(int h, int m, int s);
int getHour();
int getMinute();
int getSecond();
void setHour(int hour);
void setMinute(int minute);
void setSecond(int second);
Time getTimeFromUser(Time b);
bool validTime(Time a);
void print24Hour(Time a);
void print12Hour(Time b);
};
#endif
Schedule.h
#ifndef SCHEDULE_H
#define SCHEDULE_H
#include <iostream>
#include "time.h"
using namespace std;
class Class
{
private:
string name;
int credits;
bool majorRequirement;
double avgGrade;
string days;
Time startTime;
Time endTime;
public:
Class();
~Class();
Class(string namae, int cred, bool majorReq, double avg, string day);
//Mutate
void setName(string h);
void setCredits(int c);
void setMajorRequirement(bool set);
void setAvgGrade(double g);
void setDays(string d);
void getStartTimeFromUser(Time b);
void getEndTimeFromUser(Time e);
// Access
string getName();
int getCredits();
bool getMajorRequirement();
double getAvgGrade();
string getDays();
Time& getStartTime();
Time& getEndTime();
};
#endif
Schedule.cpp:
Class::Class()
{
string name = "";
int credits = 0;
bool majorRequirement = false;
double avgGrade = 0.0;
string days = "";
}
Time::Time()
{
int hour = 0;
int minute = 0;
int second = 0;
}
Class::Class(string namae, int cred, bool majorReq, double avg, string day)
{
name = namae;
credits = cred;
majorRequirement = majorReq;
avgGrade = avg;
days = day;
}
Time::Time(int h, int m, int s)
{
second = s;
minute = m;
hour = h;
}
Time getTimeFromUser(Time b)
{
string time = "";
string hourS, minuteS, secondS = new string();
getline(cin,time);
hourS = time.substr(0,2);
minuteS = time.substr(3,2);
secondS = time.substr(6,2);
b.hour = atoi(hourS.c_str());
b.minute = atoi(minuteS.c_str());
b.second = atoi(secondS.c_str());
return b;
}
void getStartTimeFromUser(Time b)
{
startTime = getTimeFromUser(b);
}
void getEndTimeFromUser(Time e)
{
endTime = getTimeFromUser(e);
}
Other Mutators and Accessors here.
Main is long. Here is the severely condensed version:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <iomanip>
#include "time.h"
#include "schedule.h"
using namespace std;
int main()
{
// Expecting that variables are properly declared
Class * klass = new Class[classcount];
cout << "Enter the start time for the class (format is HH:MM:SS): ";
klass[i].getStartTimeFromUser(classB);
cout << "Enter the end time for the class (format is HH:MM:SS): ";
klass[i].getEndTimeFromUser(classE);
for(int i = 0; i < classcount; i++)
{
// Data collected via getline and changed through mutators/accessors
// Problems arise when working with Time
klass[i].getStartTime().print24hour();
}
}
I get quite a few "hour, second, minute, etc." are private errors, I'm guessing I'm doing something simple in a rather wrong way. Please help.
I get a lot of this:
time.h:10:7: error: ‘int Time::hour’ is private
schedule.cpp:146:4: error: within this context
time.h:10:13: error: ‘int Time::minute’ is private
schedule.cpp:147:4: error: within this context
time.h:10:21: error: ‘int Time::second’ is private
schedule.cpp:148:4: error: within this context
schedule.cpp: In function ‘void getStartTimeFromUser(Time)’:
schedule.cpp:155:16: error: ‘setStartTime’ was not declared in this scope
schedule.cpp: In function ‘void getEndTimeFromUser(Time)’:
schedule.cpp:160:2: error: ‘endTime’ was not declared in this scope
time.h: In function ‘bool validTime(Time)’:
There are several errors in your code:
I assume class in your main() function represents an array of
Class; but this is illegal, since class is a C++ keyword.
You are trying to access a private member of a Class object
(class[i].startTime). This is illegal again. You would need a
public accessor to that data member:
You are calling a function that does not exist (print24()). If you
intended to call print24hour(), this function takes no parameters.
Putting it all together, you need to do three things:
Add an accessor for startTime in Class:
class Class
{
//...
public:
Time GetStartTime() {return startTime;}
};
Use a legal name for your array and use std::vector or std::array:
std::vector<Class> classArray;
// OR:
std::array<Class, SIZE> classArray;
Call the right methods correctly:
classArray[i].GetStartTime().print24hour();
I you want to access class[i].startTime.print24(getStartTime()) from main you need to make startTimepublic.
If this is good style is a different question.
You are trying to access the private members of a class using the object directly.
Please read about public and private access specifiers here.
class Class
{
private:
Time startTime;
public:
const Time & getStartTime(){
return startTime;
}
};
int main()
{
Class c;
c.getStartTime().print24Hour();
}
You want either that, or make startTime public.
Note the const; if you don't want the returned reference to be const, then make startTime public right now. You may think that making it private improves encapsulation; and yes, it does, as long as you don't provide read-write access to the variable, which happens if you don't mark the member function return type const.
If your printing function isn't marked const, then your const-correctness doesn't exist. If using const reference as return type here, then you have some things to fix.
Related reading: Pseudo-Classes and Quasi-Classes.