Why the function doesn't recognize an object created in main()? - c++

I have to make a Shopping Cart program for school, and there are more moving parts in this program than I've ever had to deal with. I'm trying to figure out why the function in my main.cpp can't recognize the object that I created in main(). It keeps saying that
the cart is not declared in the scope.
I still have to finish building out the menu, but I can't even get it to recognize the object that gets created in main.
I can see that the object is being properly created, because it can be manipulated within the main() no problem. Furthermore, I even have a few placeholder commands in there to get it working. The thing is that the homework assignment requires the menu to be in a function.
#include <iostream>
#include <string>
#include "ItemToPurchase.h"
#include "ShoppingCart.h"
using namespace std;
void PrintMenu()
{
while (true)
{
string choice;
cout << "MENU" << endl;
cout << "a - Add item to cart" << endl;
cout << "d - Remove item from cart" << endl;
cout << "c - Change item quantity" << endl;
cout << "i - Output item's descriptions" << endl;
cout << "o - Output shopping cart" << endl;
cout << "q - Quit" << endl;
cout << endl;
cout << "Choose an option: " << endl;
cin >> choice;
if (choice == "a") {
cart.GetDate();
}
else if (choice == "d") {
}
else if (choice == "c") {
}
else if (choice == "i") {
}
else if (choice == "o") {
}
else if (choice == "q") {
break;
}
else {
cout << "That is not a valid choice" << endl;
}
}
}
int main()
{
string name;
string date;
cout << "Enter customer's name: " << endl;
cin >> name;
cout << "Enter today's date: " << endl;
cin >> date;
cout << endl;
cout << "Customer name: " << name << endl;
cout << "Today's date: " << date << endl;
ShoppingCart cart(name, date);
ItemToPurchase apple("apple", 1, 4, "apple");
cout << cart.GetDate();
cart.AddItem(apple);
cout << cart.GetNumItemsInCart();
PrintMenu();
}
#ifndef SHOPPINGCART_H
#define SHOPPINGCART_H
#include <string>
#include <iostream>
#include <vector>
#include "ItemToPurchase.h"
using namespace std;
class ShoppingCart
{
private:
string customerName = "none";
string currentDate = "January 1, 2016";
vector<ItemToPurchase> cartItems;
public:
ShoppingCart(string name, string date);
string GetCustomerName() const;
string GetDate();
void AddItem(ItemToPurchase);
void RemoveItem(string);
void ModifyItem();
int GetNumItemsInCart();
double GetCostofCart();
void PrintTotal();
string PrintDecriptions();
};
#endif
#include <iostream>
#include <string>
#include <vector>
#include "ShoppingCart.h"
using namespace std;
ShoppingCart::ShoppingCart (string name, string date){
customerName=name;
currentDate= date;
}
string ShoppingCart::GetCustomerName() const
{
return customerName;
}
string ShoppingCart::GetDate()
{
return currentDate;
}
void ShoppingCart::AddItem(ItemToPurchase item)
{
cartItems.push_back(item);
}
void ShoppingCart::RemoveItem(string name)
{
for (int i = 0; i < cartItems.size(); i++)
{
if (cartItems.at(i).GetName() == name)
{
cartItems.erase(cartItems.begin() + i);
}
else
{
cout << "Item not found in cart. Nothing removed." << endl;
}
}
}
int ShoppingCart::GetNumItemsInCart(){
int number;
number = cartItems.size();
return number;
}
double ShoppingCart::GetCostofCart()
{
double sum = 0.0;
for (int i = 0; i < cartItems.size(); i++)
{
sum += cartItems[i].GetQuantity() * cartItems[i].GetPrice();
}
return sum;
}
#include "ItemToPurchase.h"
void ItemToPurchase::SetName(string SetItemName){
itemName = SetItemName;
}
void ItemToPurchase::SetPrice(int SetItemPrice){
itemPrice = SetItemPrice;
}
void ItemToPurchase::SetQuantity(int SetItemQuantity){
itemQuantity = SetItemQuantity;
}
string ItemToPurchase::GetName() const {
return itemName;
}
int ItemToPurchase::GetPrice() const {
return itemPrice;
}
int ItemToPurchase::GetQuantity() const {
return itemQuantity;
}
#include <string>
#include <iostream>
#ifndef ITEMTOPURCHASE_H
#define ITEMTOPURCHASE_H
using namespace std;
class ItemToPurchase
{
public:
ItemToPurchase(string a, int b, int c, string d)
{itemName = a;
itemPrice = b;
itemQuantity = c;
itemDescription =d;
}
void SetName(string SetItemName);
void SetPrice(int SetItemPrice);
void PrintItemDescription();
void SetQuantity(int SetItemQuantity);
string GetName() const;
int GetPrice() const;
int GetQuantity() const;
void SetDescription() const;
string GetDiscription() const;
void PrintItemCost() const;
private:
string itemName;
int itemPrice;
int itemQuantity;
string itemDescription;
};
#endif

[...], but I can't even get it, to recognize the object that gets created in main().
The main() and the PrintMenu() are two different functions with different scope. One can not know the variables from other, unless you pass or make known by any means.
In your case, you can pass the ShoppingCart object (i.e cart) from main() to the PrintMenu function, so that inside it will know which cart you meant for:
void PrintMenu(ShoppingCart& cart)
// ^^^^^^^^^^^^^^^^^^^^
{
// ...
}
and call the function from main() with the ShoppingCart object.
PrintMenu(cart);
That being said;
Please do not practice with using namespace std;. Read more: Why is "using namespace std;" considered bad practice?
If the member function does not modify the member, you should mark the function as const. Applies for all the getters of both ItemToPurchase and ShoppingCart classes.
When you return a non-trivial copyable objects like std::string in a getter, you should be avoiding copying. That means you might want to have changes like as below for all your getters which returns std::string:
const std::string& GetDate() const /* noexcept */
{
return currentDate;
}

This line in PrintMenu is the problem:
cart.GetDate();
The compiler looks for something called cart within the scope of that function, which does not exist. Once way to resolve this, is to pass a reference to the cart created in main to the PrintMenu function:
void PrintMenu(ShoppingCart &cart){
and call the function like this:
PrintMenu(cart);
Note that because, in the future, you'll want to modify cart in the menu, you'll need to pass it as a reference (i.e. with &) and not as a copy or constant reference.

Related

Undefined reference to Artist::Artist and Artwork::Artwork [duplicate]

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 5 months ago.
I'm new to this multi-file class stuff and I've got an undefined reference for both of my classes and I think it has something to do with my initialization and default constructor but honestly have no clue if any of this is correct at all. Any help is greatly appreciated.
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);
cin >> userBirthYear;
cin.ignore();
cin >> userDeathYear;
cin.ignore();
getline(cin, userTitle);
cin >> yearCreated;
cin.ignore();
Artist userArtist = Artist(userArtistName, userBirthYear, userDeathYear);
Artwork newArtwork = Artwork(userTitle, yearCreated, userArtist);
newArtwork.PrintInfo();
}
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:
string artistName;
int birthYear;
int deathYear;
};
#endif
Artist.cpp
#include "Artist.h"
#include <iostream>
#include <string>
using namespace std;
Artist::Artist()
{
artistName = "unknown";
birthYear = -1;
deathYear = -1;
}
string Artist::GetName() const
{
return artistName;
}
int Artist::GetBirthYear() const
{
return birthYear;
}
int Artist::GetDeathYear() const
{
return deathYear;
}
void Artist::PrintInfo() const
{
if(deathYear > 0 && birthYear > 0)
{
cout << "Artist: " << artistName <<" ("<< birthYear << " to "<< deathYear << ")" <<
endl;
}
else if(birthYear > 0 && deathYear < 0)
{
cout << "Artist: " << artistName <<" ("<< birthYear << " to present)" << endl;
}
else if(birthYear<0 && deathYear<0)
{
cout << "Artist: " << artistName << " (unknown)" << 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:
string title;
int yearCreated;
Artist artist;
};
#endif
Artwork.cpp
#include "Artwork.h"
#include <iostream>
Artwork::Artwork()
{
cout <<"Artwork has started." << endl;
title = "unknown";
yearCreated = -1;
Artist artist(); //here im not sure how to initialize an object inside of an object
}
string Artwork::GetTitle()
{
return title;
}
int Artwork::GetYearCreated()
{
return yearCreated;
}
void Artwork::PrintInfo()
{
artist.PrintInfo();
cout << "Title: " << title << ", " << yearCreated << endl;
}
I was correct, i needed to initialize both a default(no input parameters) constructor and a constructor with input parameters.
to correctly write a default and parameter constructor, do this
Artwork::Artwork(string n, int y, Artist a)
{
title = n;
yearCreated = y;
artist = a;
}//constructor with given input
Artwork::Artwork()
{
title = "unknown";
yearCreated = -1;
}//if input is not given for any fields, refer to this constructor
Notice that the default constructor does not have an object, I'm honestly not sure if there is a way to initialize a blank object and if so, why that isn't necessary.
The Artist constructor looks the same,
Artist::Artist(string name, int birth, int death)
{
artistName = name;
birthYear = birth;
deathYear = death;
}
Artist::Artist()
{
artistName = "unknown";
birthYear = -1;
deathYear = -1;
}

Error while using pointers and new operators in C++(Microsoft VS)

i was using pointers and new operator for printing different city names. But the Microsoft Visual Studio show that it is Exception thrown:read access violation.
This happen even when i write *ptr=n; or *ptr=20; ,but works properly if i give ptr=&n; (if n is the variable with some value).
Program to display names of cities
#include <iostream>
#include <cstring>
using namespace std;
class city
{
protected:
char *name;
int len;
public:
char *s;
city();
~city();
void getdata()
{
s = new char[20];
cout << "enter the name of city" << endl;
cin >> s;
len = strlen(s);
name = new char[len + 1];
strcpy_s(name, 10, s);
}
void display()
{
cout << *name << endl;
}
private:
};
city::city()
{
len = 0;//initialization
name = NULL;
}
city::~city()
{
delete[]name;
delete[]s;
}
int main()
{
city *obj[10];
int n = 0;
int en=0;
do
{
obj[n] = new city;
obj[n]->getdata();
n++;
obj[n]->display();
cout << "do you want to enter another city?" << endl;
cout << "(enter 1 for yes and 0 for no"<<endl;
cin >> en;
} while (en);
delete[]obj;
system("pause");
return 0;
}
Screenshot of error
Don't manage memory manually! Use STL to forget memory manage!
#include <iostream>
#include <string>
#include <array>
class city
{
protected:
std::string name;
public:
city() = default;
//~city();
void getdata()
{
std::cout << "enter the name of city" << std::endl;
std::cin >> this->name;
}
void display()
{
std::cout << name << std::endl;
}
};
int main()
{
std::array<city, 10> obj;
for(auto&& o : obj)
{
o.getdata();
o.display();
std::cout
<< "do you want to enter another city?" << std::endl
<< "(enter 1 for yes and 0 for no" << std::endl;
int en=0;
std::cin >> en;
if(0 == en) return 0;
}
return 0;
}
https://wandbox.org/permlink/bz4iF3LNDSyUIZPb

object is undefined in function

Im new to C++ and started working with classes recently for a school excercice.
I really cant see whats wrong and after creating an object "player" to the Hero class i can't use that object later in the "main Menu" function to call a method because i get the "identifier is undefined" error!
Any suggestions?
#include "stdafx.h"
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
class Hero
{
private:
//member variables
string playername;
public:
//constructor
Hero(string name)
{
playername = name;
}
string getName()
{
return playername;
}
};
//start 1
void mainMenu()
{
cout << " - - - |" << player.getName() << "- - - \n";
}
void setPlayer()
{
string name;
cout << "Hello, what is your name? " << endl;
getline(cin, name);
Hero player(name);
mainMenu();
}
int main()
{
int selection;
cout << "Shadow of darkness\n ";
cout << "1.) Start ";
cout << "2.) Exit ";
cin >> selection;
if (selection == 1)
setPlayer();
else if (selection == 2)
exit (0);
else
main();
return 0;
}
OK, calling main() from main() is a forbidden (as explained here), so do not do it.
Here is a typical example with your class (the class is cool as you have it, I just added an initializer list for fun):
#include <iostream>
#include <string>
using namespace std;
class Hero
{
private:
//member variables
string playername;
public:
//constructor
Hero(string name) : playername(name)
{
}
string getName()
{
return playername;
}
};
int main()
{
Hero player("Daniel");
cout << "Player's name: " << player.getName() << std::endl;
return 0;
}
Output:
Player's name: Daniel
Based on this, try to work your logic and do all sort of stuff that you long for (after reading some books/tutorials)!

Class Header , string does not name a type

Hi I'm trying to finish my homework. I have a compilation error when I try to separate a class, then call it later. But the whole test function works properly. It has the class within the whole text. Basically when i try to separate the class from the text, I have an error message.
#include <iostream>
#include<string>
using namespace std;
class Person
{
private:
string alpha;
int beta;
public:
Person(string Name, int Age)
{
alpha = Name;
beta = Age;
}
string getName()
{
return alpha;
}
int getAge()
{
if (beta < 0)
{ beta = 0;
cout << "Error. A negative age cannot be entered. " << endl;
}
if (beta > 120)
{
cout << "Damn you're old. How many heart transplants have you had? You Vampire " << endl;
}
return beta;
}
void setName(string alpha)
{
}
void setAge(int beta);
void display();
};
int main()
{
Person Lu("Jess ", 22);
Person Rose("Gary ", 49);
cout << Lu.getAge() << " " << Lu.getName() <<endl;
cout << Rose.getAge() << " " << Rose.getName() << endl;
return 0;
}`
But when i separate the class,:
#include <iostream>
#include <string>
class Person
{
private:
string alpha;
int beta;
public:
Person(string Name, int Age)
{
alpha = Name;
beta = Age;
}
string getName()
{
return alpha;
}
int getAge()
{
if (beta < 0)
{ beta = 0;
cout << "Error. A negative age cannot be entered. " << endl;
}
if (beta > 120)
{
cout << "Damn you're old. How many heart transplants have you had? You Vampire " << endl;
}
return beta;
}
void setName(string alpha)
{
}
void setAge(int beta);
void display();
};
Main file
#include <iostream>
#include "Person.h"
#include <string>
using namespace std;
int main()
{
Person Lu("Jess ", 22);
cout << Lu.getAge() << " " << Lu.getName() <<endl;
return 0;
}`
But when I separate the class i get an error in codeblocks. Please help.
You forgot to put using namespace std; in Person.h.
Also, you don't have any header guards on Person.h, which won't cause a problem in such a simple program, but will as soon as multiple files include Person.h.

C++ read/write to binary file. on program exit it gives System.AccessViolationException

This C++ program is created using Visual Studio 2010. It's a group project that has everyone in class stumped.
The program initially starts fine and the user can run through the program and add items that are written out to file. the items are read back in and displayed. When the user is done, on the program exiting return 0; it gives me "An unhandled exception of type System.AccessViolationException occurred. Attempted to read or write protected memory. This is often an indication that other memory is corrupt."
When this happens it opens up a file called utility here => for (_Iterator_base12 **_Pnext = &_Myproxy->_Myfirstiter; *_Pnext != 0; *_Pnext = (*_Pnext)->_Mynextiter) (*_Pnext)->_Myproxy = 0.
I can fix this by replacing return 0; with exit(0);
I know it's not a real fix though and just a band-aid over a bullet hole that is causing this issue.
After fixing (used very loosely here) that, then running the program again, it attempts to load the data file from the file system. It reads and loads the 1st item into a vector correctly but when it goes back to the start of the loop we see the same exception pop up, An unhandled exception of type System.AccessViolationException occurred.
This is the first project we have worked on using fstream and binary i/o. We had worked through a similar program that was just reading and writing strings w/out any issues.I believe that the issue stems from something in the fileHandler class but am having a difficult time pinpointing what is causing this issue.Any advice/help is greatly appreciated.Here is the code.stdafx.h
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <sstream>
#include <fstream>
#include <string.h>
#include <string>
#include <vector>
#include <time.h>
Week2.cpp (the main file for the project)
//Week2.cpp *******************
#include "stdafx.h"
#include "fileHandler.h"
using namespace std;
using namespace System;
int main(array<System::String ^> ^args)
{
fileHandler theFile("store.pkl");
vector<item> itemStack = theFile.getFile();
cout << "SKU Name Dept Vendor Max Order onHand" << endl;
cout << "-------------------------------------------" << endl;
for (int i = 0; i < itemStack.size(); i++)
{
cout << itemStack[i].toString() << endl;
}
vector<item> newStack;
//prompt for input
bool doneEditing = false;
while(!doneEditing)
{
int A;
int E;
int F;
int G;
string B;
string C;
string D;
string tempString;
cout << "Enter item info:" << endl << "Item SKU: ";
cin >> A;
cout << endl << "Item Name: ";
cin >> B;
cout << endl << "Item Dept: ";
cin >> C;
cout << endl << "Vendor Name: ";
cin >> D;
cout << endl << "Max Number: ";
cin >> E;
cout << endl << "Reorder Number: ";
cin >> F;
cout << endl << "OnHand Number: ";
cin >> G;
cout << endl << "Done?? Y/N: ";
cin >> tempString;
cout << endl;
item tempItem = item(A, B, C, D, E, F, G);
newStack.push_back(tempItem);
if (tempString == "Y" || tempString == "y")
{
doneEditing = true;
}
}
cout << "Saving stack to file" << endl;
theFile.putFile(newStack);
cout << "Items written to file" << endl;
vector<item> newFileStack = theFile.getFile();
cout << "After reload: " << endl;
cout << "SKU Name Dept Vendor Max Order onHand" << endl;
cout << "-------------------------------------------" << endl;
for (int i = 0; i < newFileStack.size(); i++)
{
cout << newFileStack[i].toString() << endl;
}
cout << "Thank you for using the Awesome Grocery Inventory Application" << endl;
system("PAUSE");
/*return 0; this breaks with same error as
when reading in saved file after application restart
*/
exit(0);
}
item.h
using namespace std;
#pragma once
class item
{
public:
item();
item(int sku, string name, string dept, string vendor, int max, int reorder, int onhand);
~item(void);
string toString();
int ItemSKU() const;
void ItemSKU(int val);
string ItemName() const;
void ItemName(string val);
string VendorName() const;
void VendorName(string val);
int MaxNumb() const;
void MaxNumb(int val);
int ReorderNumb() const;
void ReorderNumb(int val);
int OnHandNumb() const;
void OnHandNumb(int val);
private:
int itemSKU;
string itemName;
string itemDept;
string vendorName;
int maxNumb;
int reorderNumb;
int onHandNumb;
};
item.cpp
#include "StdAfx.h"
#include "item.h"
using namespace std;
item::item()
{
};
item::item(int sku, string name, string dept, string vendor, int max, int reorder, int onhand)
{
itemSKU = sku;
itemName = name;
itemDept = dept;
vendorName = vendor;
maxNumb = max;
reorderNumb = reorder;
onHandNumb = onhand;
}
item::~item(void)
{
}
string item::toString()
{
stringstream ss;
ss << itemSKU << "\t" << itemName << "\t" << itemDept << "\t" << vendorName << "\t" << maxNumb << "\t" << reorderNumb << "\t" << onHandNumb;
string s = ss.str();
return s;
}
int item::ItemSKU() const { return itemSKU; }
void item::ItemSKU(int val) { itemSKU = val; }
string item::ItemName() const { return itemName; }
void item::ItemName(string val) { itemName = val; }
string item::VendorName() const { return vendorName; }
void item::VendorName(string val) { vendorName = val; }
int item::MaxNumb() const { return maxNumb; }
void item::MaxNumb(int val) { maxNumb = val; }
int item::ReorderNumb() const { return reorderNumb; }
void item::ReorderNumb(int val) { reorderNumb = val; }
int item::OnHandNumb() const { return onHandNumb; }
void item::OnHandNumb(int val) { onHandNumb = val; }
fileHandler.h
#include "item.h"
using namespace std;
#pragma once
class fileHandler
{
public:
fileHandler(string);
~fileHandler(void);
vector<item> getFile();
void putFile(vector<item> &);
private:
string theFileName;
};
fileHandler.cpp
#include "stdafx.h"
#include "fileHandler.h"
using namespace std;
fileHandler::fileHandler(string name)
{
theFileName = name.c_str();
}
fileHandler::~fileHandler(void)
{
}
vector<item> fileHandler::getFile()
{
ifstream inFile;
string fileLine;
vector<item> localStack;
inFile.open(theFileName, ios::in|ios::binary);
if (inFile)
{
cout << "Getting file..." << endl;
cout << endl;
// not working on initial load if file is present at start
inFile.seekg(0);
while(!inFile.eof())
{
item tempItem;
inFile.read(reinterpret_cast< char * >(&tempItem), sizeof(item));
localStack.push_back(tempItem);
cout << "item added to stack" << endl;
} //breaks from here after reading in 1 item from saved file on reopen
} else {
ofstream newFile;
newFile.open(theFileName, ios::out|ios::binary);
newFile.close();
cout << "Creating new file..." << endl;
cout << endl;
inFile.open(theFileName, ios::in|ios::binary);
}
inFile.clear();
inFile.close();
if (localStack.size() > 0)
{
//removes some dirty data from end of stack
localStack.pop_back();
}
return localStack;
}
void fileHandler::putFile( vector<item> &items )
{
ofstream outFile;
outFile.open(theFileName, ios::out|ios::binary);
if(!outFile)
{
cerr<<"File could not be created"<<endl;
system("pause");
exit(1);
}
for (int i = 0; i < items.size(); i++)
{
outFile.write(reinterpret_cast<const char *>(&items[i]), sizeof(item));
}
outFile.clear();
outFile.close();
}
You cannot perform binary I/O this way with an object that contains std::string members. A std::string contains pointer(s) to dynamically allocated memory for its actual contents. You need to perform some type of serialization instead. The usual suggestion is Boost serialization.