Artwork label (Artist.cpp Isn't printing) - c++

main.cpp
#include "Artist.h"
#include "Artwork.h"
#include <iostream>
#include <string>
using namespace std;
int main() {
string userTitle, userArtistName;
int yearCreated, userBirthYear, userDeathYear;
getline(cin, userArtistName);
getline(cin, userTitle);
cin >> userBirthYear;
cin >> userDeathYear;
cin >> yearCreated;
Artist userArtist = Artist(userArtistName, userBirthYear, userDeathYear);
Artwork newArtwork = Artwork(userTitle, yearCreated, userArtist);
newArtwork.PrintInfo();
}
Artwork.cpp
#include "Artwork.h"
#include <iostream>
// TODO: Define default constructor
Artwork::Artwork(){
title = "Unknown";
yearCreated = -1;
}
// TODO: Define second constructor to initialize
// private fields (title, yearCreated, artist)
Artwork::Artwork(string title, int yearCreated, Artist artist){
this->title = title;
this->yearCreated = yearCreated;
this->artist = artist;
}
// TODO: Define get functions: GetTitle(), GetYearCreated()
string Artwork::GetTitle(){
return title;
}
int Artwork::GetYearCreated(){
return yearCreated;
}
// TODO: Define PrintInfo() function
// Call the PrintInfo() function in the Artist class to print an artist's information
void Artwork::PrintInfo(){
cout << "Title: " << title << ", " << yearCreated<< endl;
}
Artwork.h
#ifndef ARTWORKH
#define ARTWORKH
#include "Artist.h"
class Artwork{
public:
Artwork();
Artwork(string title, int yearCreated, Artist artist);
string GetTitle();
int GetYearCreated();
void PrintInfo();
private:
// TODO: Declare private data members - title, yearCreated
string title;
int yearCreated;
// TODO: Declare private data member artist of type Artist
Artist artist;
};
#endif
Artist.h
#ifndef ARTISTH
#define ARTISTH
#include <string>
using namespace std;
class Artist{
public:
Artist();
Artist(string artistName, int birthYear, int deathYear);
string GetName() const;
int GetBirthYear() const;
int GetDeathYear() const;
void PrintInfo() const;
private:
// TODO: Declare private data members - artistName, birthYear, deathYear
string artistName;
int birthYear;
int deathYear;
};
#endif
Artist.cpp
#include "Artist.h"
#include <iostream>
#include <string>
using namespace std;
// TODO: Define default constructor
Artist::Artist(){
artistName = "Unknown";
birthYear = -1;
deathYear = -1;
}
// TODO: Define second constructor to initialize
//private fields (artistName, birthYear, deathYear)
Artist::Artist(string artistName, int birthYear, int deathYear){
this->artistName = artistName;
this->birthYear = birthYear;
this->deathYear = deathYear;
}
// TODO: Define get functions: GetName(), GetBirthYear(), GetDeathYear()
string Artist::GetName() const{
return artistName;
}
int Artist::GetBirthYear()const {
return birthYear;
}
int Artist::GetDeathYear() const{
return deathYear;
}
// TODO: Define PrintInfo() function
void Artist::PrintInfo() const{
if( birthYear >=0 && deathYear == -1){
cout << "Artist: " << artistName << "(" << birthYear << "to present"<< ")"<< endl;
}
else if(birthYear >=0 && deathYear >=0){
cout << "Artist: " << artistName << "(" << birthYear << "to " << deathYear << ")"<< endl;
}
else{
cout << "Artist: " << artistName << " (" << "unknown" << ")"<< endl;
}
}
Given main(), complete the Artist class (in files Artist.h and Artist.cpp) with constructors to initialize an artist's information, get member functions, and a PrintInfo() member function. The default constructor should initialize the artist's name to "unknown" and the years of birth and death to -1. PrintInfo() displays "Artist:", then a space, then the artist's name, then another space, then the birth and death dates in one of three formats:
(XXXX to YYYY) if both the birth and death years are nonnegative
(XXXX to present) if the birth year is nonnegative and the death year is negative
(unknown) otherwise
Complete the Artwork class (in files Artwork.h and Artwork.cpp) with constructors to initialize an artwork's information, get member functions, and a PrintInfo() member function. The default constructor should initialize the title to "unknown", the year created to -1. PrintInfo() displays an artist's information by calling the PrintInfo() function in the Artist class, followed by the artwork's title and the year created. Declare a private field of type Artist in the Artwork class.
Ex: If the input is:
Pablo Picasso
Three Musicians
1881
1973
1921
1881 and 1973 being the birth and death years respectively, with 1921 being the year the work was created, the output is:
Artist: Pablo Picasso (1881 to 1973)
Title: Three Musicians, 1921
My issue Is when I test this input I only get... (in a different .h file)
Title: Distant Muses, 2000
I was wondering why void Artist::PrintInfo() wont output anything and would be great if anyone could guide me to the right direction!
Thank You in advance!

Reading through description, your Artwork class should contain PrintInfo() method, which on it's own should call Artist::PrintInfo() once invoked. Add printing the artist info before printing it's own info in the Artwork::PrintInfo() method and you should be good to go. It should look like this:
void Artwork::PrintInfo(){
artist.Printinfo(); // Not 100% sure this is correct syntax, check carefully.
cout << "Title: " << title << ", " << yearCreated<< endl;
}
Also, worth noting that you can 'merge' constructors. Instead of this(Yes I'm aware it's 'required', but you can take a step further):
Artist::Artist(){
artistName = "Unknown";
birthYear = -1;
deathYear = -1;
}
// TODO: Define second constructor to initialize
//private fields (artistName, birthYear, deathYear)
Artist::Artist(string artistName, int birthYear, int deathYear){
this->artistName = artistName;
this->birthYear = birthYear;
this->deathYear = deathYear;
}
You can have this:
Artist::Artist(string artistName="Unknown", int birthYear=-1, int deathYear=-1){
this->artistName = artistName;
this->birthYear = birthYear;
this->deathYear = deathYear;
}
By setting default values, if constructor isn't provided any value, aka default constructor is used, everything will be set to default value, in this case "Unknown" and -1's. If someone provides name, you will have name and -1's and so on.

Related

Why is my elements in my vector of objects not updating upon calling one of the objects member function?

I have been trying to do debug this for a long time using visual studio debugger but I can't figure out why my function emp.setHoursWorked(hWorked); in recordHoursWorkedForEmployee only seems to be update numOfHoursWorked while in recordHoursWorkedForEmployee, as soon the program exits the function the numOfHoursWorked of all Employees in the vector go back to 0. Below is the code in question. Any help would be appreciated.
#ifndef PAYROLLSYSTEM
#define PAYROLLSYSTEM
#include "Employee.h"
#include "Paycheck.h"
#include <string>
#include <vector>
using namespace std;
class PayRollSystem
{
public:
//custom constructor gets company name
PayRollSystem(string);
void createEmployee(string, string,string, double);
void removeEmployee(string);
void recordHoursWorkedForEmployee(string);
void issuePaychecks();
private:
string companyName;
vector<Employee> companyEmployees;
};
#endif
void PayRollSystem::createEmployee(string empId, string fName, string lName, double hWage)
{
Employee temEmp = Employee(empId, fName, lName, hWage);
companyEmployees.push_back(temEmp);
}
void PayRollSystem::recordHoursWorkedForEmployee(string empId)
{
for (Employee emp : companyEmployees)
{
if (emp.getEmployeeId() == empId)
{
int hWorked = 0;
cout << "What are the hours the worked for " + emp.getEmployeeId() + " during current pay period?" << endl;
cin >> hWorked;
//TODO: For some reason this line is not updating the hours worked. Must fix!
emp.setHoursWorked(hWorked);
cout << "Hours for " + emp.getEmployeeId() + " have been changed to " << emp.getHoursWorked() << endl;
}
}
}
I excluded the header file here in order to not paste too many things not relevant to the problem i'm facing, only implementations of member functions relevant to the problem provided
//Overloaded constructor to be used with PayRollSystem
Employee::Employee(string empId, string fName, string lName, double hWage)
{
employeeId = empId;
firstName = fName;
lastName = lName;
hourlyWage = hWage;
numOfHoursWorked = 0;
}
void Employee::setHoursWorked(int hWorked)
{
if (hWorked >= 0)
numOfHoursWorked = hWorked;
else
{
cout << "Invalid number of hours worked." << endl;
exit(EXIT_FAILURE);
}
}
string Employee::getEmployeeId() const
{
return employeeId;
}
This line makes a copy of each employee:
for (Employee emp : companyEmployees)
The variable emp is a copy of the object in the container. So if you update this you are only updating the copy. Each iteration you get a new value copied into emp but any changes are not reflected in the original object.
You probably meant:
for (Employee& emp : companyEmployees)
^^^
Here emp is a reference to the object inside the vector. If you modify this you are modifying the original value inside the vector.

possible circular referencing?

Maybe it's because I've been staring at this for 5 hours straight and I'm just reading over the obvious solution, but Xcode states that my vector of objects (that is declared in a header file) is undeclared in one .cpp file; however, my other .cpp file can access the vector, so I'm not sure what the problem is. Maybe my header files are out of place, or I'm unintentionally "circular referencing"?? Suggestions please?
publications.h
#ifndef PUBLICATIONS_H
#define PUBLICATIONS_H
#include "std_lib_facilities.h"
class Publication {
private:
string
publication_title,
publication_author,
publication_year,
publication_genre,
publication_media,
publication_target_age,
publication_ISBN;
bool currently_checked_out;
public:
Publication(string title, string author, string year, string genre, string media, string target_age, string ISBN, bool checked_out) {
publication_title = title;
publication_author = author;
publication_year = year;
publication_genre = genre;
publication_media = media;
publication_target_age = target_age;
publication_ISBN = ISBN;
currently_checked_out = checked_out;
}
Publication(){};
};
#endif /* PUBLICATIONS_H */
library.h
#ifndef LIBRARY_H
#define LIBRARY_H
#include "std_lib_facilities.h"
class Publication;
class Library {
private:
vector<Publication> lb;
public:
Library(){};
void documentation();
void list_all_publications();
void new_publication(string title, string author, string year, string genre, string media, string target_age, string ISBN, bool currently_checked_out);
};
#endif /* LIBRARY_H */
patron.h
#ifndef PATRON_H
#define PATRON_H
#include "std_lib_facilities.h"
class Publication;
class Patron {
private:
string
customer_name,
customer_telephone;
public:
void check_out_publication(string publication_requested);
void return_publication(string check_in_publication_name);
void check_out();
bool is_checked_out();
Patron(){};
};
#endif /* PATRON_H */
library.cpp (works perfectly fine, can access vector in library.h)
#include "library.h"
#include "patron.h"
#include "publications.h"
#include "std_lib_facilities.h"
Patron p;
void Library::documentation() {
cout << "\n-----Create a new publication----\n";
cout << "You will enter all the necessary info for a new publication (title, author, year, genre, media, target age, and ISBN).\n";
cout << "\n----List all Publications-----\n";
cout << "List all publications that have been entered (in this current session).\n";
cout << "\n---Check out Publication----\n";
cout << "You will enter your name and telephone number and the publication will be checked out.\n";
cout << "\n-----Return Publication------\n";
cout << "A previously checked out publication will be marked as returned.\n";
}
void Library::new_publication(string title, string author, string year, string genre, string media, string target_age, string ISBN, bool checked_out) {
lb.push_back(Publication(title, author, year, genre, media, target_age, ISBN, checked_out));
}
void Library::list_all_publications() {
for (int i = 0; i < lb.size(); i++) {
cout << "Title: " << "\tChecked Out: " << p.is_checked_out() << endl;
}
}
patron.cpp (problematic file, cannot access vector in library.h)
#include "publications.h"
#include "library.h"
#include "patron.h"
#include "std_lib_facilities.h"
void Patron::check_out_publication(string publication_requested) {
// check to make sure publication isn't already checked out.
for (int i = 0; i < lb.size(); i++) {
if ((publication_requested == lb[i].publication_title) && lb[i].currently_checked_out) {
cout << "Sorry, this publication is currently checked out." << endl;
} else if ((publication_requested == lb[i].publication_title) && !(lb[i].currently_checked_out)) {
cout << "Enter your name: ";
getline(cin, customer_name);
cout << "Enter your telephone number (no dashes/no spaces): ";
cin >> customer_telephone;
} else {
continue;
}
}
}
void Patron::return_publication(string check_in) {
for (int i = 0; i < lb.size(); i++) {
if ((check_in == lb[i].publication_title) && lb[i].currently_checked_out) {
// marked as no longer checked out.
lb[i].currently_checked_out = false;
}
}
}
bool Patron::is_checked_out() {
return currently_checked_out;
}
void Patron::check_out() {
currently_checked_out = true;
}
Error in patron.cpp
USE OF UNDECLARED IDENTIFIER "lb"
lb is a private member of the Library class. You can access it in your library.cpp file because you are using it within a Library member function. Whereas in the Patron class you're directly accessing it. But the compiler sees it as just another variable, which you haven't declared. Likely you need to add an accessor to Library.

error in C++: out-of-line definition

CustomerInfo.cpp
#include "CustomerInfo.h" // <==== Funtion Definition
CustomerInfo::CustomerInfo() // <==== The Scope Resolution which is two colons :: gives me access to the class
{
newZipCode = 0;
}
CustomerInfo::CustomerInfo(string name, string address, int zipCode)
{
newName = name;
newAddress = address;
newZipCode = zipCode;
}
CustomerInfo::~CustomerInfo()
{
}
string CustomerInfo::getName() const
{
return newName;
}
string CustomerInfo::getAddress() const
{
return newAddress;
}
int CustomerInfo::getZipCode() const
{
return newZipCode;
}
The main.cpp file
#include <iostream>
#include <string>
#include "CustomerInfo.h"
using namespace std;
int main()
{
string name;
string address;
int zipCode;
cout << "Enter your name: ";
getline (cin, name);
cout << "Enter your address" << endl;
getline (cin, address);
cout << "Enter your ZipCode: ";
cin >> zipCode;
CustomerInfo Real_1(name, address, zipCode);
cout << endl << " Name: " << Real_1.getName() << endl <<
"Address: " << Real_1.getAddress() << endl <<
"ZipCode: " << Real_1.getZipCode() << endl;
return 0;
}
The CustomerInfo.h file
#ifndef CUSTOMERINFO_H
#define CUSTOMERINFO_H
// Header ==> Function Declaration
#include <iostream>
#include <string>
using namespace std;
class CustomerInfo
{
public:
CustomerInfo(); // <==== Default Constructor
CustomerInfo(string, int); // <==== Overload Constructor
~CustomerInfo(); // <===== Destructor - Done using an object it will be destroyed out of memory'
string getName() const; // <==== Accessor Functions - Return member variables one value at a time. In addition, no void function will be used.
// getName - returns name of person
string getAddress() const;
// getAddress - returns address of person
int getZipCode() const;
// getZipCode - returns zipcode of person
private:
//Member Variables
string newName;
string newAddress;
int newZipCode;
}; // <=== Requires semicolon after brackets for classes
#endif // CUSTOMERINFO_H
The error I receive is out-of-line definition of 'CustomerInfo' does not match any declaration in 'CustomerInfo'
The following line is the error
CustomerInfo::CustomerInfo(string name, string address, int zipCode)
Your problem seems to be that you define a constructor
CustomerInfo::CustomerInfo(string name, string address, int zipCode)
which does not appear in the class definition (in CustomerInfo.h). The closest one is
CustomerInfo(string, int);
but it doesn't match the signature. Just replace it with
CustomerInfo(string name, string address, int zipCode);
to your class definition in the header file.

Undefined Reference c++ lost

#include "assert.h"; // for some reason assert wouldn't work on my compiler without this
#include <iostream>
#include <string>
#include <limits> // This is helpful for inputting values. Otherwise, funny stuff happens
using namespace std;
class Product
{
public:
Product();
Product(string the_name, int the_price, int number_of);
string return_name();
void reduce_amount();
void print_data() const;
private:
string prod_name; // name of your product
int price_in_cents; // it's price in cents
int amount; // the number of the product that you have
};
Product::Product()
{
prod_name = "NULL_NAME: NEED DATA";
price_in_cents = 0;
}
Product::Product(string the_name, int the_price, int number_of)
{
assert(the_price>0);
assert(number_of>0);
assert(number_of<21);
assert(prod_name !="NULL_NAME: NEED DATA");
prod_name = the_name;
price_in_cents = the_price;
amount = number_of;
}
void Product::print_data() const
{
cout<<prod_name << endl;
cout<<"The price in cents is: " <<price_in_cents<< endl;
cout<< "Amount left: " << " " << amount << endl;
}
void Product::reduce_amount()
{
amount = amount -1;
}
string Product::return_name()
{
return prod_name;
}
class Vending_Machine
{
public:
Vending_Machine();
void empty_coins();
void print_vend_stats();
void add_product();
Product buy_product();
private:
int income_in_cents;
Product product1();
Product product2();
Product product3();
Product product4();
Product product5();
};
void Vending_Machine::empty_coins()
{
cout << "The total amount of money earned today is " << income_in_cents << " cents" << endl;
income_in_cents = 0;
cout << "All the coins have been withdrawn. The balance is now zero." << endl;
}
void Vending_Machine::print_vend_stats()
{
cout<< "Total income thus far: " << income_in_cents << endl;
if (product1().return_name() != "NULL_NAME: NEED DATA")
{
//stuff happens
}
}
int main()
{
return 0;
}
So, I'm not sure if I did all the identation correctly, but I'm having a problem with the boolean statement in vending machine print_vend_stats() function. It's saying I am making an undefined fereence to product1(). What does this mean?
When you declare
Product product1();
you declare a member function, the parentheses is what makes it a function.
If you drop the parentheses
Product product1;
you declare a member variable, an actual instance of the Product class.
Another example, you wouldn't write e.g.
int income_in_cents();
do declare income_in_cents as a variable, now would you?
It doesn't matter if the type is a primitive type like int, or a class like Product, Member variables are declared like normal variables like you do anywhere else.

Whats wrong with my class [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I don't know why but when i create an object with my class and use the default constructor, when i try to pass the variable named cash to the accessor user2.setCash(cash) which purpose is to primary set cash equal to new_cash, it gives a large value like 1.222256e+461 or something like that. Why does that happen? If i use my overload constructor it works fine.
main.cpp
#include <iostream>
#include <string>
#include "Bank.h"
using namespace std;
int main()
{
string name;
int id;
double cash;
bank user2;
cout << "\n\nPlease type your name: ";
getline(cin >> ws, name);
user2.setName(name);
cout << "Enter an id number: ";
cin >> id;
user2.setID(id);
cout << "Enter your cash: ";
cin >> cash;
cout << cash << endl;
user2.setCash(cash);
cout << "\nAlright " << user2.getName() << ", current cash: " << user2.getCash();
cout << "\nChoose how much would you like to Deposit: ";
cin >> cash;
user2.deposit(cash);
cout << "New amount is: " << user2.getCash() << " For user ID: " << user2.getID() << "\n\n";
bank::printStatic();
return 0;
}
Bank.h
#ifndef BANK_H
#define BANK_H
#include <iostream>
#include <string>
using namespace std;
class bank
{
public:
// Default Constructor
bank();
// Overload Constructor
bank(string, int, double);
// Destructor
~bank();
// Accessor Functions
string getName() const;
int getID() const;
double getCash() const;
// Mutator Functions
void setName(string);
void setID(int);
void setCash(double);
// Functions
void withdraw(double);
void deposit(double);
static void printStatic();
private:
// Member Variables
string new_name;
int new_id;
double new_cash;
// Static Member Variables
static int num_of_accounts;
static double total_cash;
};
#endif
Bank.cpp
#include "Bank.h"
// Static Variables
int bank::num_of_accounts = 0;
double bank::total_cash = 0.0;
// Default Constructor
bank::bank()
{
int new_id = 0;
double new_cash = 0.0;
++num_of_accounts; // New object is created e.g. a person so total accounts must be increased.
}
// Overload Constructor
bank::bank(string name, int id, double cash)
{
new_name = name;
new_id = id;
new_cash = cash;
++num_of_accounts; // New object is created e.g. a person so total accounts must be increased.
total_cash += new_cash; // New object is created e.g. a person so his/hers cash must be added to the total cash of the bank.
}
// Destructor
bank::~bank()
{
--num_of_accounts; // When Destructor is called to destroy an object (e.g. a person) then the id must be dropped by 1 cause the person e.g. (left).
total_cash -= new_cash; // And the balance he had to be removed so it is not counted in total cash avaliable in the bank cause he e.g. (left).
}
// Accessor Functions
string bank::getName() const
{
return new_name;
}
int bank::getID() const
{
return new_id;
}
double bank::getCash() const
{
return new_cash;
}
// Mutator Functions
void bank::setName(string name)
{
new_name = name;
}
void bank::setID(int id)
{
new_id = id;
}
void bank::setCash(double cash)
{
cout << new_cash << endl;
total_cash -= new_cash; // We must remove his prior cash which we holded in the total so we can then use the new value suplied.
new_cash = cash;
total_cash += new_cash; // Here we add the new cash (balance) he/she has.
}
void bank::withdraw(double cash)
{
new_cash -= cash;
total_cash -= cash;
}
void bank::deposit(double cash)
{
new_cash += cash;
total_cash += cash;
}
void bank::printStatic()
{
cout << "Total users are: " << num_of_accounts << endl;
cout << "Total cash in bank is: " << total_cash << endl;
}
You need to initialize all primitive type members in the constructor.
Otherwise you get indeterminate values
Also, the non-default constructor is buggy:
// Default Constructor
bank::bank()
{
int new_id = 0;
double new_cash = 0.0;
....
^ sets values of local variables, not the member variables
I'd suggest to use the initilization lists:
// Default Constructor
bank::bank() : new_name(), new_id(0), new_cash(0.0)
{
++num_of_accounts;
}
// Overload Constructor
bank::bank(string name, int id, double cash)
: new_name(name), new_id(id), new_cash(cash)
{
++num_of_accounts;
total_cash += new_cash;
}
You could also combine the two:
bank::bank(string name = "", int id = 0, double cash = 0.0)
: new_name(name), new_id(id), new_cash(cash)
{
++num_of_accounts;
total_cash += new_cash;
}
In your default constructor, you're declaring local variables with the same names as the member variables. Then you're setting these local variables instead of assigning the members. Get rid of the type declarations so they're normal assignments.
bank::bank()
{
new_id = 0;
new_cash = 0.0;
++num_of_accounts; // New object is created e.g. a person so total accounts must be increased.
}