Scope and accessor functions with second constructors? - c++

So basically my professor gave us the class student and told us to implement all functions and write a main for the function. I am trying to do this but I am having trouble figuring out the errors that are arising, in all of my accessor functions it is telling me that nCredits, gpa, and s aren't declared in the scope. I assume this has something to do with the second constructor, but I am not sure what exactly the issue is. The second constructor and the displayStRec function were also provided to our class, I just don't know how to do this program with the variables in the member function being renamed as they have been.
#include <iostream>
using namespace std;
class student
{
public:
student();
student(string s, double gpa, int nCredits);
~student(); //destructor
void changeCredits(int nCredits);
int getCredits();
void changeGPA(double gpa);
double getGPA();
void displayStRec();
private:
string name;
double GPA;
int credits;
};
student::student()
{
name = "No name yet";
GPA = 0;
credits = 0.0;
cout << "Default constructor entered!" << endl;
}
student::student(string s, double gpa, int nCredits)
{
name = s;
GPA = gpa;
credits = nCredits;
cout << "Second constructor entered!" << endl;
}
void student::changeCredits(int nCredits){
cout << "Enter credits earned:" << endl;
cin >> nCredits;
}
int student::getCredits(){
return nCredits;
}
void student::changeGPA(double gpa){
cout << "Enter GPA: " << endl;
cin >> gpa;
}
double student::getGPA(){
return gpa;
}
void student::displayStRec()
{
cout << " Name: " << s <<endl;
cout << " GPA: " << gpa <<endl;
cout << "Credits: " << nCredits <<endl;
}
student::~student()
{
cout << "Destructor entered!" << endl;
}
int main()
{
student s1,s2("John",4.0,42);
s2.changeCredits(nCredits);
s2.getCredits();
s2.changeGPA(gpa);
s2.getGPA();
s2.displayStRec();
return 0;
}

You've got three variables that you're using that aren't declared. I'll hit them one by one.
Missing s
void student::displayStRec()
{
cout << " Name: " << s <<endl;
cout << " GPA: " << gpa <<endl;
cout << "Credits: " << nCredits <<endl;
}
In this function, you are trying to output some variable s that isn't declared within the scope of displayStRec. You used s in the constructor to initialize the name, copying it to member variable name. Well, s is gone now! But name persists for the lifetime of the object. So, just use name instead.
void student::displayStRec()
{
cout << " Name: " << name <<endl; //Change it here
cout << " GPA: " << gpa <<endl;
cout << "Credits: " << nCredits <<endl;
}
Missing nCredits and gpa
In your main function you're using two variables that aren't declared.
int main()
{
student s1,s2("John",4.0,42);
s2.changeCredits(nCredits); //What nCredits?
s2.getCredits();
s2.changeGPA(gpa); //What gpa?
s2.getGPA();
s2.displayStRec();
return 0;
}
This leads to the question... what are you trying to change their credits to? What are you trying to change their gpa to? In other words, shouldn't your program have input parameters? Perhaps somewhere in your assignment your professor told you what values to provide. You will need constants of some kind, or you will need to gather user input from cin.
Oh and by the way, this makes zero sense
void student::changeGPA(double gpa){
cout << "Enter GPA: " << endl;
cin >> gpa;
}
This function will accept user input and update the variable gpa, which is declared in local scope and immediately discarded. Not very useful.
Also, it accepts an input value (double gpa) but also collects input from cin. Why do both? Can't update it to two values at the same time!
My guess is that is supposed to update the object's GPA, which is declared in member scope. Like this:
void student::changeGPA(){
cout << "Enter GPA: " << endl;
cin >> GPA;
}
or
void student::changeGPA(double gpa){
GPA = gpa;
}
Conclusion
One of the following must be true:
You copied the code examples incorrectly
The professor gave you a trick question
The professor is sort of clueless or perhaps a bit overworked

I've gone ahead and removed the sloppy second constructor functions my professor is trying to force on us and this program now works fine:
#include <iostream>
using namespace std;
class student
{
public:
student();
student(string s, double gpa, int nCredits);
~student(); //destructor
void changeCredits();
int getCredits();
void changeGPA();
double getGPA();
void displayStRec();
private:
string name;
double GPA;
int credits;
};
student::student()
{
name = "No name yet";
GPA = 0;
credits = 0.0;
cout << "Default constructor entered!" << endl;
}
student::student(string s, double gpa, int nCredits)
{
name = s;
GPA = gpa;
credits = nCredits;
cout << "Second constructor entered!" << endl;
}
void student::changeCredits(){
cout << "Enter credits earned: ";
cin >> credits;
}
int student::getCredits(){
return credits;
}
void student::changeGPA(){
cout << "Enter GPA: ";
cin >> GPA;
}
double student::getGPA(){
return GPA;
}
void student::displayStRec()
{
cout << " Name: " << name <<endl;
cout << " GPA: " << GPA <<endl;
cout << "Credits: " << credits <<endl;
}
student::~student()
{
cout << "Destructor entered!" << endl;
}
int main()
{
student s1,s2("John",4.0,42);
s2.changeCredits();
s2.getCredits();
s2.changeGPA();
s2.getGPA();
s2.displayStRec();
return 0;
}

here is a suggested solution however I don't know what your teacher orders:
!: add string to inclusion
2: use only member data not non members
3: either make changeCredits and changeGPA take 0 argument and inside it ask for inputs or input outside and and pass to it.
#include <iostream>
#include <string>
using namespace std;
class student
{
public:
student();
student(string s, double gpa, int nCredits);
~student(); //destructor
void changeCredits();
int getCredits();
void changeGPA();
double getGPA();
void displayStRec();
private:
string name;
double GPA;
int credits;
};
student::student() :
name("No name yet"), GPA(0.0), credits(0)
{
cout << "Default constructor entered!" << endl;
}
student::student(string s, double gpa, int nCredits) :
name(s), GPA(gpa), credits(nCredits)
{
cout << "Second constructor entered!" << endl;
}
void student::changeCredits()
{
cout << "Enter credits earned:" << endl;
cin >> credits;
cout << endl;
}
int student::getCredits()
{
return credits;
}
void student::changeGPA()
{
cout << "Enter GPA: " << endl;
cin >> GPA;
cout << endl;
}
double student::getGPA()
{
return GPA;
}
void student::displayStRec()
{
cout << " Name: " << name <<endl;
cout << " GPA: " << GPA <<endl;
cout << "Credits: " << credits <<endl;
}
student::~student()
{
cout << "Destructor entered!" << endl;
}
int main()
{
student s1, s2("John", 4.0, 42);
s2.changeCredits();
s2.getCredits();
s2.changeGPA();
s2.getGPA();
s2.displayStRec();
return 0;
}

Related

no instance of overloaded function matches the specified type (C++)

#include <iostream>
#include <string>
using namespace std;
class student {
private:
string sname;
float gpa;
public:
student(string name, float g = 0.0);
~student();
};
struct student {
string name;
int gpa;
void display();
};
student::student(string name, float g) { // **this is where I get the error**
cout << "student constructor is running..." << endl;
student stu;
stu.name += name;
stu.gpa = g;
}
student::~student() {
// cout << "Student No." << endl;
cout << "student destructor is running..." << endl;
}
void student::display() {
cout << "Student Name: " << name << endl;
cout << "Student GPA: " << gpa << endl;
}
It is a student header file.
The error came out: no instance of constructor "student::student" matches the argument list.
I don't get it why and how to fix this.
compiler think student as structure,
change student sturture name

C++ Virtual Void

Okay, so I have a parent class called employee and 3 subclass called manager,researcher and engineer. I made a vector and want to list them. this is the how I process the making.
vector <Employee*,Manager*> EmployeeDB;
Employee *temp;
temp = new Manager(first, last, salary, meetings, vacations);
EmployeeDB.push_back(temp);
I have no problem in making the vector, my concern is listing the info. all 3 subclasses have firstname, lastname and salary but they're difference is that they have different data members which is unique, example the Manager has the int value vacation and the Engineer has the int value experience so on and so forth.
Employee.h:
#include <iostream>
#include <string>
using namespace std;
#ifndef EMPLOYEE_h
#define EMPLOYEE_h
class Employee
{
public:
Employee();
Employee(string firstname, string lastname, int salary);
string getFname();
string getLname();
int getSalary();
virtual void getInfo();
private:
string mFirstName;
string mLastName;
int mSalary;
};
#endif
Employee.cpp:
#include "Employee.h"
#include <iostream>
#include <string>
using namespace std;
Employee::Employee()
{
mFirstName = "";
mLastName = "";
mSalary = 0;
}
Employee::Employee(string firstname, string lastname, int salary)
{
mFirstName = firstname;
mLastName = lastname;
mSalary = salary;
}
string Employee::getFname()
{
return mFirstName;
}
string Employee::getLname()
{
return mLastName;
}
int Employee::getSalary()
{
return mSalary;
}
void Employee::getInfo()
{
cout << "Employee First Name: " << mFirstName << endl;
cout << "Employee Last Name: " << mLastName << endl;
cout << "Employee Salary: " << mSalary << endl;
}
Main:
#include <vector>
#include <iostream>
#include <string>
#include "Employee.h"
#include "Engineer.h"
#include "Manager.h"
#include "Researcher.h"
using namespace std;
vector <Employee*> EmployeeDB;
Employee *temp;
void add()
{
int emp, salary, vacations, meetings, exp, c;
string first, last, type, school, topic;
bool skills;
do
{
system("cls");
cout << "===========================================" << endl;
cout << " Add Employee " << endl;
cout << "===========================================" << endl;
cout << "[1] Manager." << endl;
cout << "[2] Engineer." << endl;
cout << "[3] Researcher." << endl;
cout << "Input choice: ";
cin >> emp;
system("cls");
} while (emp <= 0 || emp > 3);
cout << "===========================================" << endl;
cout << " Employee Info " << endl;
cout << "===========================================" << endl;
cout << "Employee First name: ";
cin >> first;
cout << "Employee Last name: ";
cin >> last;
cout << "Employee Salary: ";
cin >> salary;
switch (emp)
{
case 1:
cout << "Employee numbers of meetings: ";
cin >> meetings;
cout << "Employee numbers of vacations: ";
cin >> vacations;
temp = new Manager(first, last, salary, meetings,vacations);
EmployeeDB.push_back(temp);
delete temp;
break;
case 2:
cout << endl;
cout << "[1]YES [2]NO" << endl;
cout << "Employee C++ Skills: ";
cin >> c;
if (c == 1)
{
skills = true;
}
else
{
skills = false;
}
cout << "Employee Years of exp: ";
cin >> exp;
cout << "(e.g., Mechanical, Electric, Software.)" << endl;
cout << "Employee Engineer type: ";
cin >> type;
temp = new Engineer(first, last, salary, skills, exp, type);
EmployeeDB.push_back(temp);
delete temp;
break;
case 3:
cout << "Employee School where he/she got his/her PhD: ";
cin >> school;
cout << "Employee Thesis Topic: ";
cin >> topic;
temp = new Researcher(first, last, salary, school, topic);
EmployeeDB.push_back(temp);
delete temp;
break;
}
}
void del()
{
}
void view()
{
for (int x = 0; x < (EmployeeDB.size()); x++)
{
cout << EmployeeDB[x]->getInfo();
}
}
void startup()
{
cout << "===========================================" << endl;
cout << " Employee Database " << endl;
cout << "===========================================" << endl;
cout << "[1] Add Employee." << endl;
cout << "[2] Delete Employee." << endl;
cout << "[3] List Employees." << endl;
cout << "[4] Exit." << endl;
cout << "Please Enter Your Choice: ";
}
int main(int argc, char** argv)
{
bool flag = true;
int choice;
do {
do
{
system("cls");
system("pause>nul");
startup();
cin >> choice;
} while (choice < 0 || choice >4);
switch (choice)
{
case 1:
add();
break;
case 2:
del();
break;
case 3:
view();
break;
case 4:
flag = false;
system("EXIT");
break;
}
} while (flag == true);
return 0;
system("pause>nul");
}
I am getting error on the view() function.
It says no operator<< matches these operands
binary '<<': no operator found which takes a right hand operand of type void etc etc.
The problem is that the getInfo has return type void and you are trying to put that return value into cout.
It's important to understand that the code std::cout << val actually calls the function operator<<(ostream& out, const objectType& val) where objectType is the type of 'val'.
In your case the type is void, and there is simply no implementation of operator<< that takes void as a type. hence the error "no operator found which takes a right hand operand of type void...".
In order to fix your issue you have a few options:
Change view() to be
for (...)
{
EmployeeDB[x]->getInfo();
}
Change getInfo() to return a string the info as you'd like:
std::string getInfo()
{
std::string info;
info =...
return info;
}
Create an operator<< for Employee and change view to call it:
view()
{
for (...)
{
std::cout << EmployeeDB[x];
}
}

Try to do cin >> string[array] and there is an error (""string subscript out of range")

The code :
class DataBase {
private:
int age, stuNumNew;
string stuName, command;
string ver = "Alpha";
float stuNum = 1;
public:
void Start() {
cout << "Welcome back to Sudent DataBase <ver " << ver << ">." << endl;
cout << "Type 'Add' for add a student.";
cin >> command;
if (command == "Add") {
Add();
}
else if (command == "Search") {
cout << "Student number: ";
cin >> stuNumNew; //Get input from user
cout << "Name: " << stuName[stuNumNew] << endl << "Age: " << age[&stuNumNew] << endl;
Start();
}
}
void Add() {
cout << "Name: ";
**cin >> stuName[stuNum] * *; //get the name
cout << "Age: ";
cin >> age[stuNum]; //get the age
cout << "Student Number: " << stuNum;
stuNum = stuNum++;
stuNumNew = stuNum;
Start();
}
};
Vectors allow you to create variable size arrays
The issue you're having is caused by using a fixed size variable. What you need in this case is a vector because what you are trying to do is assign names and numbers to arrays that are of variable sizes so that you can add new students in your program.
Vectors allow you to do just that.
Here is the modified code:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class DataBase {
private:
int searchInput;
/* declare a vector of type int to contain your students' ages */
vector<int> studentAges;
/* declare a vector of type std::string to contain your students' names */
vector<string> studentNames;
string command;
string ver = "Alpha";
/* stuNum is removed because vectors keep track of their own sizes */
public:
void Start() {
cout << "Welcome back to Student DataBase <ver " << ver << ">." << endl;
cout << "Type 'Add' to add a new student or type 'Search' to search the database of students." << endl << " > ";
cin >> command;
if (command == "Add") {
Add();
} else if (command == "Search") {
/* You may want to build in a conditional that checks if there are any students yet. */
cout << "Student number: ";
cin >> searchInput;
if (searchInput < studentNames.size()) {
/* Make sure that the users input (the number) is actually a student's id number
* otherwise reject their input to keep the program from crashing or having undefined behavior.
*/
cout << "Name: " << studentNames[searchInput] << endl << "Age: " << studentAges[searchInput] << endl;
} else {
cout << "Student number invalid" << endl;
}
} else {
/* Tell them if their input is invalid */
cout << "Invalid option." << endl;
}
Start();
}
void Add() {
/* Append new positions for input */
studentNames.push_back("");
studentAges.push_back(0);
cout << "Name: ";
cin >> studentNames.back();
cout << "Age: ";
cin >> studentAges.back();
/* The student number is the newest index of the vector */
cout << "Student Number: " << studentNames.size() - 1 << endl;
}
};
int main() {
DataBase d;
d.Start();
}
You can also combine your variables studentNames and studentAges into a students vector if you create a class (or struct) that keeps both values together:
class Student {
public:
Student(string name, int age) {
this->age = age;
this->name = name;
}
string name;
int age;
};
Then you can use it with vector:
vector<Student> students;
NOTE:
You may want to add some input protecting because if you enter a string where it wants a number it breaks the program.

Bank Accounts Using Vectors (Deposit and Withdrawal)

I am working on a project that should allow you to create 3 accounts of the form (Name,AccountNumber,Balance) and then gives you the following options:
1) Add an account.
2) Close and existing account.
3) Deposit an amount.
4) Withdraw an account
5) No request.
Up till now, I am able to successfully create 3 accounts, display them, add another account, display them again, delete an account and display them once again. However, I am having trouble figuring out a way to deposit or withdraw money from a specific account.
So to be clear, my question is: How do I access the balance of a chosen account and deposit/withdraw an amount (keeping in mind that I am using vectors to save all accounts)?
The following is my code:
main.cpp
#include <iostream>
#include <vector>
#include "bank.hpp"
#include <string>
#include <fstream>
#include <stdlib.h>
using namespace std;
void fillaccounts(vector<bank>&);
void printaccounts(const vector<bank>&);
void createaccount(vector<bank>&);
void depositaccount(vector<bank>&);
void deleteaccount (vector<bank>&);
int main() {
vector<bank> mybank;
fillaccounts(mybank);
for (int i=0;i<5;i++) {
cout << "Please choose one of the following requests: " << endl;
cout << "(1) Create a new account." << endl;
cout << "(2) Close an existing account." << endl;
cout << "(3) Deposit an amount in one of your accounts." << endl;
cout << "(4) Withdraw an amount from one of your accounts." << endl;
cout << "(5) No request." << endl;
cout << "Enter your choice here: " << endl;
int request;
cin >> request;
switch (request) {
case 1:
createaccount(mybank);
printaccounts(mybank);
break;
case 2:
deleteaccount(mybank);
printaccounts(mybank);
break;
case 3:
depositaccount(mybank);
printaccounts(mybank);
break;
case 4:
break;
case 5:
break;
}
}
}
void fillaccounts(vector<bank>& newmybank) {
string name;
int accountnumber;
double balance;
for (int i=0; i<3;i++) {
cout << "Enter your first name: " << endl;
cin >> name;
cout << "Enter account number: " << endl;
cin >> accountnumber;
cout << "Enter the amount you want to deposit: " << endl;
cin >> balance;
bank newAccount(name, accountnumber,balance);
newmybank.push_back(newAccount);
cout << endl;
}
cout << endl;
}
void createaccount(vector<bank>& newmybank) {
string name;
int accountnumber;
double balance;
cout << "Enter your first name: " << endl;
cin >> name;
cout << "Enter account number: " << endl;
cin >> accountnumber;
cout << "Enter the amount you want to deposit: " << endl;
cin >> balance;
bank newAccount(name,accountnumber,balance);
newmybank.push_back(newAccount);
cout << endl;
}
void printaccounts(const vector<bank>& newmybank) {
for (unsigned int i=0; i<newmybank.size();i++) {
cout << "(" << newmybank[i].getname() << "," << newmybank[i].getaccountnumber() << "," << newmybank[i].getbalance() << ")" << endl;
}
cout << endl;
}
void deleteaccount(vector<bank>& newmybank) {
string name;
cout << "Please enter your name to delete your account: " << endl;
cin >> name;
cout << endl;
for (int i=0; i<newmybank.size(); i++) {
if (newmybank[i].newname == name) {
newmybank.erase(newmybank.begin()+i);
}
}
}
Bank.cpp
#include "Bank.hpp"
#include <iostream>
#include <string>
#include <vector>
using namespace std;
bank::bank() {
newname=' ';
newaccountnumber=0;
newbalance=0.0;
}
bank::bank(string name,int accnum,double amount) {
newname=name;
newaccountnumber=accnum;
newbalance=amount;
}
string bank::getname() const {
return newname;
}
int bank::getaccountnumber() const {
return newaccountnumber;
}
double bank::getbalance() const {
return newbalance;
}
void bank::setname(string name) {
newname=name;
}
void bank::setaccountnumber(int accountnumber) {
newaccountnumber=accountnumber;
}
void bank::setbalance(double balance) {
newbalance=balance;
}
Bank.hpp
class bank {
public:
string newname;
int newaccountnumber;
double newbalance;
bank(); //Constructor
bank(string,int,double); //Overload Constructor
string getname() const;
int getaccountnumber() const;
double getbalance() const;
void setname(string);
void setaccountnumber(int);
void setbalance(double);
};
Any advice on how to follow up?
Thank you guys!
One way to do this is to add a function to your bank class which adds a specific amount to the account balance and then call this method when you want to change the account value (i.e. to deposit/withdraw), or create 2 separate methods.
Something like:
void bank::deposit(int num)
{
newbalance += num;
}
You would then have a user specify a bank account number (or name), because I don't think you would want to change every balance from every account. A function getAccountIndex might loop through every account to find the specified data, then return the index in your vector.
When you have the index you can invoke the deposit method like so mybank[index].deposit(amount);
Note that your variables in the bank class are public, so you don't really need get/set methods, but this is considered bad practice so you should make those variables private.

error C2601: "Name": local function definitions are illegal

I'm new to C++ and learning about Inheritance and Polymorphism. We require to write an employee project that have 4 types of employee (BasePlusCommission, CommisisonEmployee, Salaried and TipWorker). My project has one main() class that I used switch method for each type of employee. I got stuck on TipWorker where we have to do Polymorphism. Here what I got so far.
int main()
{
void virtualViaPointer(const Employee * const);
{
cout << "Enter First Name: " << endl;
cin >> firstName;
cout << "Enter Last Name: " << endl;
cin >> lastName;
cout << "Enter SSN: " << endl;
cin >> SSN;
if (SSN.length() == 9)
{
SSN = true;
}
else
{
cout << "Please enter SSN again with 9 digits only:" << endl;
cin >> SSN;
}
cout << "Enter wages: " << endl;
cin >> wage;
cout << "Enter hours: " << endl;
cin >> hours;
cout << "Enter tips: " << endl;
cin >> tips;
TipWorker employee4(firstName, lastName, SSN, wage, hours, tips);
employee4.print();
cout << fixed << setprecision(2);
vector < Employee * > employees(1);
employees[0] = &employee4;
cout << "Employee processed polymorphically via dynamic binding: \n\n";
cout << "Virtual function calls made off base-class pointers:\n\n";
for (const Employee *employeePtr : employees)
virtualViaPointer(employeePtr);
void virtualViaPointer(const Employee * const baseClassPtr)
{
baseClassPtr->print();
cout << "\nEarned $" << baseClassPtr->earnings() << "\n\n";
}
break;
}
}
When I run the project, I came up with this error:
error C2601: "virtualViaPointer": local function definitions are
illegal
void virtualViaPointer(const Employee * const baseClassPtr)
{
baseClassPtr->print();
cout << "\nEarned $" << baseClassPtr->earnings() << "\n\n";
}
Can anyone please help me? Thank you so much!
You may not define one function inside an other function. Any function definition shall be outside any other function definition.
Place the definition of virtualViaPointer outside the body of main.
You can have a declaration of a function inside a function, but no definition(!) of that function. However, you can have a local struct/class or lambda in the function:
#include <iostream>
void f()
{
void print(); // mostly useless - maybe a most vexing parse error
struct Print {
static void apply(const char* s) { std::cout << s << '\n'; }
}
Print::apply("Hello");
auto lambda = [] (const char* s) { std::cout << s << '\n'; };
lambda("World");
}
Note: A local struct does not require C++11 (Also, it may look nicer while debugging)