I've submitted an assignment which has met all the criteria except that I'm not allowed to have global variables except if they're constants, and I had my vector set up as a global variable.
I'm now finding it impossible to have my vector used in my header file as well as my class functions file and my main class file.
I have a primary class and a derived class, and the vector items are of the derived class. I've put my vector definition in the header now in the primary class:
vector<Stock> arrStock;
But when trying to add objects into the vector from the input file and subsequently perform actions on it, I am able to either set up the functions inside the classes functions class, OR call the functions I've set up in the main class (if I have the functions set up as static).
What am I doing wrong? Currently with the way the code has been set up, I'm having error E0245 "a nonstatic member reference must be relative to a specific object" on all the functions that I'm calling in my main class. It's probably worth noting that when I had the vector set up as a global variable, the functions were defined as static and they worked perfectly, so I'm open to the fact that they need to be static and that my issue is with the application of the array in the Assignment2_classes.cpp file instead.
Please see my code snippets below:
Assignment2.h:
class Product
{
private:
string title, surname;
long long int isbn;
double wholesalePrice;
public:
string getTitle();
string getSurname();
long long int getIsbn();
double getWholesalePrice();
void setTitle(string);
void setSurname(string);
void setIsbn(long long int);
void setWholesalePrice(double);
Product();
~Product();
Product(string, string, long long int, double);
void importProducts();
void newProduct();
void delProduct();
void runReport();
void checkStock();
void clrStock();
vector<Stock> arrStock;
};
// creating the derived class Stock
class Stock :public Product
{
public:
double retailPrice;
char bookFormat;
int stockLevel;
double getRetailPrice();
char getBookFormat();
int getStockLevel();
void setRetailPrice(double);
void setBookFormat(char);
void setStockLevel(int);
Stock();
~Stock();
Stock(string, int, char, string, double, long long int, double);
void setStockInfo(long long int, string, string, double, int, double, char);
};
Assignment2_classes.cpp:
void Product::importProducts()
{
// code adapted from: https://stackoverflow.com/questions/16878259/how-to-read-in-a-set-of-values-from-a-text-file-then-go-to-the-next-line-and-do
// telling the function which input file it is reading from
ifstream productsFile("products_v5.txt");
// creating local variables
Stock aStock;
double tempRetailPrice = 0;
string undsc = "_";
string space = " ";
size_t position;
std::cout << "Importing books...\n";
// reading the books into an array
while (productsFile >> aStock.title >> aStock.stockLevel >> aStock.bookFormat >> aStock.surname >> aStock.wholesalePrice >> aStock.isbn)
{
// replacing the underscores in the title names with spaces so the output looks better
// code adapted from https://www.educba.com/c-plus-plus-replace/
while ((position = aStock.title.find(undsc)) != string::npos)
{
aStock.title.replace(position, 1, space);
}
// calculating the retail prices of the books depending on their format
switch (aStock.bookFormat)
{
case 'a': tempRetailPrice = aStock.wholesalePrice * 1.43;
break;
case 'e': tempRetailPrice = aStock.wholesalePrice * 1.08;
break;
case 'h': tempRetailPrice = aStock.wholesalePrice * 1.45;
break;
case 's': tempRetailPrice = aStock.wholesalePrice * 1.27;
break;
}
aStock.setRetailPrice(tempRetailPrice);
arrStock.push_back(aStock);
}
// letting the user know how many books have been added and how many books are currently in the array
std::cout << "\n" << to_string(arrStock.size()) << " books have been added.\n";
std::cout << "\nBiblioden Books currently has " << to_string(arrStock.size()) << " different books.\n";
}
Assignment2_main.cpp:
int main()
{
char createBook;
char deleteBook;
char viewReport;
char checkOrders;
// creating the heading of the output
cout << "-----------------------------------------------------------------------------------------\n" << " Biblioden Systems\n" << "-----------------------------------------------------------------------------------------\n";
ifstream productsFile("products_v5.txt");
// checking whether the file is open and gracefully exiting if it can't be opened
if (!productsFile.is_open())
{
cout << "\nCannot open file.\n";
return 1;
}
Product::importProducts();
//closing the file
productsFile.close();
cout << "\nWould you like to enter a new book? (Y/N): ";
cin >> createBook;
if (createBook == 'Y' || createBook == 'y')
{
Product::newProduct();
}
cout << "\nWould you like to delete a book? (Y/N) ";
cin >> deleteBook;
if (deleteBook == 'Y' || deleteBook == 'y')
{
Product::delProduct();
}
cout << "\nWould you like to view a report? (Y/N) ";
cin >> viewReport;
if (viewReport == 'Y' || viewReport == 'y')
{
ofstream report("report.txt");
// checking whether the file is open and gracefully exiting if it can't be opened
if (!report.is_open())
{
cout << "\nCannot open file.\n";
return 1;
}
else
{
Product::runReport();
// closing the file
report.close();
}
}
cout << "\nWould you like to check the order list against the stock list? (Y/N) ";
cin >> checkOrders;
if (checkOrders == 'Y' || checkOrders == 'y')
{
ifstream ordersFile("orders_v5.txt");
// checking whether the file is open and gracefully exiting if it can't be opened
if (!ordersFile.is_open())
{
cout << "\nCannot open file.\n";
return 1;
}
else
{
Product::checkStock();
// closing the file
ordersFile.close();
}
}
// clearing out the array once the user is finished with it
Product::clrStock();
return 0;
}
CodePudding user response:
As mentioned in comments, the call Product::importProducts();
requires importProducts()
to be a static
member function of Product
.
In your case, you can't declare it as static
(and it doesn't make sense to do so) since you use (non-static) class members inside the function.
You need an instance of Product
to call the member functions on.
For example:
Product p; // Create an instance of Product
p.importProducts(); // Call importProducts() from (and for) the previously created instance
On the other hand, if you don't want to create any instance of Product
and thus you want a unique vector for the whole program, you may mark your members (and members functions) static
to solve your issue.
CodePudding user response:
The declaration of your member variable arrStock
comes before the class Stock is declared. You cannot reference a class that has not been declared yet. You have to make your vector as a vector of pointer (or shared_ptr) then you can forward declare the class, before declaring Product, with:
class Stock;