1. Explanation of error and my logic
I am having trouble figuring out why using a referenced object from one class into a separate class is not working the way I thought it would. I have included streamlined code below for this example with a Main.cpp and 2 other classes, named InventoryStorage and ShoppingExperience.
The InventoryStorage class stores names from a .txt file into a vector, and has a typical getter that I can make an object for in Main.cpp to output these names: invStObj.getFileInvData(i)
My problem is that I wish to use this getter in several other classes as well, WITHOUT making a new instance of the object, InventoryStorage invStObj; that was made in Main.cpp
Instead, I attempted to make a reference for this object, InventoryStorage& invStRefObj = invStObj; that my other class ShoppingExperience.cpp will use in order to utilize the getFileInvData() function in this class as well.
When I run this code, it should output the desired output but instead, the actual output is cut short when it reaches the Item List in Inventory part. My reference object in my 2nd class will not work with the getter function from the 1st class properly.
cout << invStObj.getFileInvData(i) << endl; that is in Main.cpp properly outputs "test items" followed by the names
cout << invStRefObj.getFileInvData(i) << endl; from ShoppingExperience class just outputs "Item List in Inventory" and then errors without outputting any names
Desired Output.................................................... Actual Output
test items test items
book book
movie movie
food food
game game
Item List in Inventory Item List in Inventory
book
movie
food
game
I receive an error, "vector subscript out of range" because my ShoppingExperience.cpp is trying to use the getter with a new empty vector. Using a reference of the object did not seem to protect it from creating a new instance of that class which is what I was trying to prevent in the first place.
Please refer to my code located below for clarification
2. Question: Is it possible to reference to an object from another class similar to my failed attempt? Is there some alternate format or function that I can use to achieve this? I would like Main.cpp and my ShoppingExperience.cpp to use the same object and class instance for the InventoryStorage class functions
3. InventoryStorage.h, InventoryStorage.cpp, Main.cpp, ShoppingExperience.h, ShoppingExperience.cpp are shown below in their entirety for citation
InventoryStorage.h
#pragma once
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
using std::string;
using std::vector;
class InventoryStorage
{
public:
InventoryStorage();
void storeFileInvData(string); //opens and stores file names to vector, invDataCl
string getFileInvData(int); //returns names from vector, invDataCl
private:
string fileNameCl;
string lineCl;
vector<string> invDataCl;
};
InventoryStorage.cpp
#include "InventoryStorage.h"
InventoryStorage::InventoryStorage() {
}
void InventoryStorage::storeFileInvData(string fileNameTmp) {
fileNameCl = fileNameTmp;
std::ifstream openInvFileCl;
openInvFileCl.open(fileNameCl);
while (getline(openInvFileCl, lineCl, ',')) {
lineCl.erase(remove(lineCl.begin(), lineCl.end(), ' '));
invDataCl.push_back(lineCl);
}
}
string InventoryStorage::getFileInvData(int invDataTmp) {
return invDataCl[invDataTmp];
}
Main.cpp
#include <iostream>
#include "InventoryStorage.h"
#include "ShoppingExperience.h"
using namespace std;
int main() {
InventoryStorage invStObj; //obj to create instance of InventoryStorage class
InventoryStorage& invStRefObj = invStObj; //reference to obj that I can use in other classes, so that I can use same instance
invStObj.storeFileInvData("inventoryData.txt");
cout << "test items" << endl;
for (int i = 0; i < 4; i ) {
cout << invStObj.getFileInvData(i) << endl; //object and getter work fine in main, output names
}
cout << "\n";
ShoppingExperience shopExpObj; //program errors, ShoppingExperience class will not out any names
//ShoppingExperience class uses the reference object unsuccessfully
return 0;
}
ShoppingExperience.h
#pragma once
#include <iostream>
using std::cout;
using std::endl;
class ShoppingExperience {
public:
ShoppingExperience();
private:
};
ShoppingExperience.cpp
#include "ShoppingExperience.h"
#include "InventoryStorage.h"
ShoppingExperience::ShoppingExperience() {
InventoryStorage invStRefObj; //trying to reference first instance of object for InventoryStorage class inside ShoppingExperience class
cout << "Item List in Inventory" << endl; //only outputs "Item List in Inventory"
for (int i = 0; i < 4; i ) {
cout << invStRefObj.getFileInvData(i) << endl;
}
//no names are outputted, then errors and program stops
} //vector subscript out of range (the vector is empty)
//doesn't appear to be using object of same instance like I thought the referenced object would ensure
CodePudding user response:
InventoryStorage invStRefObj
is a completely new object unrelated to the reference declared in main
. You need to pass the object via reference to the constructor of ShoppingExperience
:
In main
:
ShoppingExperience shopExpObj(invStObj);
In the header:
class ShoppingExperience {
public:
ShoppingExperience(InventoryStorage& invStRefObj);
private:
};
In the cpp:
ShoppingExperience::ShoppingExperience(InventoryStorage& invStRefObj) {
cout << "Item List in Inventory" << endl; //only outputs "Item List in Inventory"
for (int i = 0; i < 4; i ) {
cout << invStRefObj.getFileInvData(i) << endl;
}
}
Note that it's not necessary to create a reference in main
. You can just pass an object directly to a function/method/constructor that expects a reference.
You should avoid putting using namespace
in header files as these will then apply to all places that header is included.