I have a very specific question on a program I am writing which makes a battleship game. I have the header file provided to me and I must implement the function definitions within the defined header file. I will post my entire code, however, I am only having trouble implementing the function void ship::printShip() const. I need it to access information for a class within a class and I have a function provided that I am using under location void print() const, however, it wants me to create a pointer in order to access the information under print. I will post the function definitions and the header file along with the error message.
Header file:
#ifndef BATTLESHIP_H_
#define BATTLESHIP_H_
// coordinates (location) of the ship and shots
class location{
public:
location(); // void constructor, assigns -1 to X
void pick(); // picks a random location
void fire(); // asks the user to input coordinates of the next shot
void print() const; // prints location in format "a1"
// returns true if the two locations match
friend bool compare(location, location);
private:
static const int fieldSize = 5; // the field (ocean) is fieldSize X fieldSize
int x; // 1 through fieldSize
char y; // 'a' through fieldSize
};
// contains ship's coordinates (location) and whether is was sunk
class ship{
public:
ship(); // void constructor, sets sunk=false
bool match(location&) const; // returns true if this location matches
// the ship's location
bool isSunk() const { return sunk; } // checks to see if the ship is sunk
void sink(); // sets "sunk" member variable of the ship to true
void setLocation(const location&); // deploys the ship at the specified location
void printShip() const; // prints location and status of the ship
private:
location loc;
bool sunk;
};
// contains the fleet of the deployed ships
class fleet{
public:
void deployFleet(); // deploys the ships in random locations
// of the ocean
bool operational() const; // returns true if at least
// one ship in the fleet is not sunk
bool isHitNSink(const location &); // returns true if there was a deployed
// ship at this location (hit) and sinks it
// otherwise returns false (miss)
void printFleet() const; // prints out locations of ships in fleet
private:
static const int fleetSize = 5; // number of battleships
int check(const location &); // returns index of the ship
// that matches location
// -1 if none match
ship ships[fleetSize]; // battleships of the fleet
};
#endif /* BATTLESHIP_H_ */
Here are my function definitions:
#include "battleship.h"
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
const int FLEET_SIZE = 5;
const int FIELD_SIZE = 5;
void location::pick(){
x = rand() % FIELD_SIZE;
if (x == 0){
x = 1;
}
y = rand() % FIELD_SIZE;
switch (y)
{
case 0:
y = 'A';
break;
case 1:
y = 'B';
break;
case 2:
y = 'C';
break;
case 3:
y = 'D';
break;
case 4:
y = 'E';
break;
}
}
void location::fire(void){
cout << "Enter the number of the grid to fire on ";
cin >>y;
cout << "Enter the letter of the grid to fire on ";
cin >> x;
}
void location::print() const{
cout << y << x;
}
bool compare(location one,location two){
if ((one.x == two.x)&&(one.y==two.y)){
return true;
}
return false;
}
location::location(){
x = -1;
}
void ship::setLocation(const location& location){
loc= location;
}
bool ship::match(location& location)const{
if (compare(loc, location)){
return true;
}
return false;
}
void ship::printShip()const{
cout << loc.print << endl;
cout << sunk << endl;
}
void ship::sink(){
sunk = true;
}
Here is the .cpp
#include "battleship.h"
#include <iostream>
#include <ctime>
#include <cstdlib>
using std::cout; using std::cin; using std::endl;
/// this is main function
const int FLEET_SIZE = 5;
const int FIELD_SIZE = 5;
int main(){
srand(time(NULL));
//
// checking location object
//
location mySpot, userShot;
mySpot.pick(); // selecting a new random location
cout << "Randomly selected location is: "; mySpot.print();
cout << "Input location: ";
userShot.fire(); // having user input a location
if (compare(mySpot, userShot))
cout << "Random location matches user input.\n";
else
cout << "Random location does not match user input.\n";
//
// checking ship object
//
ship myShip;
myShip.setLocation(mySpot); // placing ship at mySpot location
if(myShip.match(userShot))
cout << "myShip\'s location matches user input.\n";
else
cout << "myShip's location does not match user input.\n";
if(!myShip.isSunk()){
cout << "myship is not sunk yet, sinking it.\n";
myShip.sink();
}
cout << "myShip\'s status is: "; myShip.printShip();
//
// checking fleet object
//
/* // uncomment this part once you are done debugging above code
fleet myFleet;
myFleet.deployFleet(); // fleet is deployed at random locations
if(myFleet.operational())
cout << "Some ships of myFleet are still up.\n";
if(myFleet.isHitNSink(userShot))
cout << "there was a ship at userShot location, no it is sunk.\n";
else
cout << "there was no ship at userShot location.\n";
cout << "myFleet\'s status is: "; myFleet.printFleet();
*/
}
Here is the error for printShip() const
Error 1 error C3867: 'location::print': function call missing argument list; use '&location::print' to create a pointer to member
If someone could just explain what I need to edit in order to make printShip() const print the location of the ship as intended that is all need.
You are simply missing the parentheses in the call to location::print:
void ship::printShip() const {
cout << loc.print() << endl;
cout << sunk << endl;
}
It happens. But learn to recognize the message from your compiler: function call missing argument list actually means: "if you want to write a function call, add an argument list." And "use '&location::print' to create a pointer to member" tries to tell you the alternative, i.e., when you really want a pointer to the method, use &location::print.
Later
location::print() doesn't return anything, so you might want to change that. Or just use that call as it prints to cout right now.
void ship::printShip() const {
loc.print();
cout << endl;
cout << sunk << endl;
}
Related
So I have a program that has a class that represents a player (also called player). The player needs to have a name, password, amount of experience, a position, and an inventory of four items. The program needs to create three (hardcoded) players each with a name, password, experience amount, position, and an inventory of four items. I have it mostly done except one thing, the inventory array. I have it partially set up with a setInv and getInv to both set and get the inventory, but I'm uncertain on how to use getInv to put items into the inventory so I can use getInv to display it. I tried putting an already filled array in the class but the display outputs none of the items. I also tried playerOne("a"); and playerOne.setInv() = "a"; to but both fail. With the first giving me the error of "too many arguments in function call".
I'm also getting the errors The second one give me two errors of "Index '4' is out of valid index range '0' to '3' for possibly stack allocated buffer 'inv'." and "Reading invalid data from 'inv': the readable size is '112' bytes, but '140' bytes may be read."
I'm very new to C++ and would appreciate any help, thank you!
#pragma warning(disable: 4996)
#include<string>
#include <iostream>
#include <cstdlib>
#include <string>
using namespace std;
//player class
class player {
public:
//name
void setName(string name) {
this->name = name;
} //setName end
string getName() {
return name;
} //getName end
//password
void setPass(string pass) {
this->pass = pass;
} //setPass end
string getPass() {
return pass;
} //getPass end
//experience
void setXP(int xp) {
this->xp = xp;
} //setXP end
int getXP() {
return xp;
} //getXP end
//position
void setPosX(int xPos) {
this->xPos = xPos;
} //setPosX end
void setPosY(int yPos) {
this->yPos = yPos;
} //setPosY end
int getPosX() {
return xPos;
} //getPosX end
int getPosY() {
return yPos;
} //getPosY end
//inventory
string setInv() {
string inv[4];
this->inv = inv[4];
} //setInv end
string getInv() {
return inv;
} //getInv end
void display();
private:
string name;
string pass;
string inv;
int xp = 0;
int xPos = 0;
int yPos = 0;
}; //class end
void player::display() {
//playerOne output
cout << "Player Info - \n";
cout << "Name: " << getName() << "\n";
cout << "Password: " << getPass() << "\n";
cout << "Experience: " << getXP() << "\n";
cout << "Position: " << getPosX() << ", " << getPosY() << "\n";
cout << "Inventory: ";
for (int i = 0; i < 4; i++) {
getInv();
cout << "\n\n";
} //for end
}
int main()
{
//playerOne
player playerOne;
playerOne.setName("Porcupixel");
playerOne.setPass("PokeHerFace2008");
playerOne.setXP(1477);
playerOne.setPosX(16884);
playerOne.setPosY(10950);
//playerTwo
player playerTwo;
playerTwo.setName("Commandroid");
playerTwo.setPass("RodgerRodger00110001");
playerTwo.setXP(73721);
playerTwo.setPosX(6620);
playerTwo.setPosY(36783);
//playerThree
player playerThree;
playerThree.setName("BumbleBeast");
playerThree.setPass("AutoBotsRule7");
playerThree.setXP(20641);
playerThree.setPosX(15128);
playerThree.setPosY(46976);
playerOne.display();
playerTwo.display();
playerThree.display();
return 0;
} //main end
All right, first for your inventory set up, you could do it in a bunch of diverse ways, to begin within your 'setInv' function you are not receiving parameters which is weird since what are you trying to initialize your inventory with? You could initialize all values passing in an array of strings if that makes sense, also from what I gather from your getInv function it looks like you're trying to store the contents of your array of strings in your private var 'inv' however you might be failing to do this since it is only a string and not an array of string, meaning it can only store ONE string or object.
Answering your question more specifically, your 'getInv' is not returning anything because you are not storing anything into your string to begin with:
Just to explain a little bit more.
string setInv() {
string inv[4];
this->inv = inv[4];
} //setInv end
In this code, you are declaring a new array of strings of size 4, then saying that inv is equal to inv[4] which is never initialized therefore you're not storing anything, anyway as I explained earlier it doesn't look like the right way to do what you're trying to!
The task is to:
Create the abstract class Train nd two derived Passenger/Freight.
Create a container. Type of container dynamic array (the size of the array is defined as arguments of the constructor).
Save the results to the file and delete them from it.
Search in the container and print the train by his number.
I have some questions about where is better to create userInput, storeToArray functions. In the menu file or class as a virtual function or create one more h/cpp?
Why does is the error C2228(VS19) in Menu.cpp/void storeToArray()?
#include"Train.h"
void storeToArray()
{
Train* t;
t = new Train();
t.userInput;
//collection.push_back(t);
}
1>Menu.cpp
1>C:\Users\Admin\source\repos\Menu.cpp(29,3): warning C4002: too many arguments for function-like macro invocation 'assert'
1>C:\Users\Admin\source\repos\Menu.cpp(88,1): warning C4002: too many arguments for function-like macro invocation 'assert'
1>C:\Users\Admin\source\repos\Menu.cpp(105,5): error C2039: 'userInput': is not a member of 'Train'
1>C:\Users\Admin\source\repos\train.h(7): message : see declaration of 'Train'
Does my way of solving this problem is optimal?
How can I make the program better?
https://github.com/brenqP/Course
Menu.h:
#pragma once
#include "PassengerTrain.h"
#include "FreightTrain.h"
#include "train.h"
void greeting();
void showMenu();
void userMenu();
void userInput();
void storeToArray();
//void printInput();
menu.cpp
#include "Menu.h"
#include "file.h"
#include <iostream>
#include <cassert>
void greeting() { std::cout << "Welcome to the Train simulator!\n\n"; }
void showMenu()
{
std::cout<<
"1)Create new train route for the passenger train.\n"<<
"2)Create new train route for the freight train.\n"<<
"3)Save results to the file.\n" <<
"4)Open results from the file.\n" <<
"5)Find train by number.\n"<<
"6)Exit.\n\n";
}
void userMenu()
{
showMenu();
std::cout << "Choose one of the options by printing the number.\n";
int option = 0;
std::cin >> option;
std::cout << "You have chosen the " << option << " option\n";
assert("Invalid input.Please try again later.",option > 0 && option < 7);
//system("cls");
switch (option)
{
case 1:
{//Train:: ;
userInput();
userMenu();
break;
}
case 2:
{
userInput();
userMenu();
break;
}
case 3:
storeToFile();
userMenu();
break;
case 4:
executeFile();
userMenu();
break;
case 5:std::cout << "later";
userMenu();
break;
case 6:
{
std::cout << "\nOkay, see you next time.\n";
std::exit(0);
break;
}
default:
std::cout << "Something went wrong, please try again later\n";
std::exit (0);
}
}
void userInput()
{
std::cout << "Input the number of the train you`re willing to create\n";
int number = 0;
std::cin >> number;
assert(number > 0);
std::cout << "Input the path of the train you`re willing to create\n"
<< "Ex. London-Paris\n";
std::string path{ "N / A - N / A" };
std::cin >> path;
std::cout << "Input the time of the departure\n"
<< "Ex. 23.22\n";
double time_of_departure{ 0 };
std::cin >> time_of_departure;
assert(time_of_departure >= 0 && time_of_departure < 24.0,
"Invalid time of the departure ");
//system("cls");
Train g{ number,path,time_of_departure };
g.print();
}
error
void storeToArray()
{
Train* t;
t = new Train();
t.userInput;
//collection.push_back(t);
}
Train.cpp
#include "train.h"
Train::Train(int number, std::string path, double time_of_departure):
m_number{ number },
m_path{ path },
m_time_of_departure{ time_of_departure }
{
}
Train::~Train()
{
}
//void Train::setPassengerTrain()
//{
//Train:setNumber();
//
//}
void Train::setNumber(int number)
{
m_number = number;
}
void Train::setPath(int path)
{
m_path = path;
}
void Train::setTime_of_departure(int time_of_departure)
{
m_time_of_departure = time_of_departure;
}
void Train::print()
{
std::cout<< "The train number \t" <<
getNumber() << " \t "<<
getPath() << " \tis departed at\t " <<
//bug if there is a /t; print 121314 instead of 1
getTime_of_departure()<<'\n' << std::endl;
}
train.h
#pragma once
#include <string>
#include<iostream>
#include <cassert>
#include <vector>
class Train
{
protected:
int m_number{0};
std::string m_path{"N/A-N/A"};
double m_time_of_departure{0};
public :
//some constructors
Train() = default;
Train(int number, std::string path, double time_of_departure);
//destructor
virtual ~Train();
//void setPassengerTrain();
virtual int getNumber() { return m_number; }
void setNumber(int number);
virtual std::string getPath() { return m_path; }
void setPath(int path);
virtual double getTime_of_departure(){ return m_time_of_departure; }
void setTime_of_departure(int time_of_departure);
void print();
};
PassengerTrain.h
#pragma once
#include "train.h"
class PassengerTrain :public Train
{
int m_number{ 0 };
std::string m_path{ "N/A-N/A" };
double m_time_of_departure{ 0 };
public:
//some constructors
PassengerTrain() = default;
PassengerTrain(int number, std::string path, double time_of_departure);
//destructor
~PassengerTrain();
//void setPassengerTrain();
int getNumber() { return m_number; }
void setNumber(int number);
std::string getPath() { return m_path; }
void setPath(int path);
double getTime_of_departure() { return m_time_of_departure; }
void setTime_of_departure(int time_of_departure);
void print();
};
PassengerTrain.cpp
#include"PassengerTrain.h"
PassengerTrain::PassengerTrain(int number, std::string path, double time_of_departure):
m_number{ number },
m_path{ path },
m_time_of_departure{ time_of_departure }{}
PassengerTrain::~PassengerTrain()
{
}
void PassengerTrain::print()
{
std::cout << "The passenger train number \t" <<
getNumber() << " \t " <<
getPath() << " \tis departed at\t " <<
//bug if there is a /t; print 121314 instead of 1
getTime_of_departure() << '\n' << std::endl;
}
The freightTrain is the same as passengerTrain.
This is maybe not a complete answer (since you did not provide a minimally reproducible example to actually work on) but there are many obvious things to fix. Before even looking at details:
C++ is case sensitive, Train and train are two different things to C++, this also applies to include files Train.h and train.h. You CANNOT mix those: fix.
C++ is very flexible in terms of your text formatting, but in some places white-spaces are mandatory. In particular #include"Train.h" must be #include "Train.h"
Let's look at:
#include"Train.h" // at white space --> #include "Train.h"
void storeToArray()
{
Train* t;
t = new Train();
t.userInput;
//collection.push_back(t);
}
where userInput is not a method or property of Train but a free function defined in Menu.h. Thus, very good practice is to also include #include "Menu.h" (this won't fix any of your problems yet).
Another issue is of course that t is a pointer, not an object. You cannot use the dot operator t., but you have to use the arrow operate t->. But this also does not solve any of your problems yet.
It seems to me what you want to achieve is to ask the user for input, create a new Train object, and store it in a collection. For this you better start by changing the definition of void userInput(); in Menu.h to Train* userInput();
Then in "menu.cpp" you also change it to Train* userInput() { and furthermore you change the last to lines of the userInput function from
Train g{ number,path,time_of_departure };
g.print();
(which actually does accomplish nothing useful) to
Train* train = new Train(number, path, time_of_departure);
train->print();
return train; // <-- this is really important since it return your train to the caller
If you do those changes, you at least can produce trains, and store them in a collection as you wish.
I'm working on a simple dice game project which requires me to instantiate several copies of a custom class.
vector <Player> playerList;
playerList.resize(totalNumPlayers); //totalNum is grabbed from cin
for (int x = 0; x < totalNumPlayers; x++)
{
playerList.at(x).setname("Player" + to_string(x + 1));
//playerList[x] = p;
playerList.at(x).printName();
cout << playerList[0].returnName() << " " << playerList[1].returnName() << " " << playerList[2].returnName() << endl;
}
Player Class:
//Declarations
string playerName;
int playerChips;
Player::Player()
{
//Default constructor for when player is created
playerChips = 3;
playerName = "DEFAULT_PLAYER_NAME";
}
void Player::setname(string var)
{
playerName = var;
}
string Player::returnName()
{
return(playerName);
}
void Player::printName()
{
cout << playerName << endl;
}
void Player::addChips(int x)
{
playerChips += x;
}
void Player::removeChips(int x)
{
playerChips -= x;
}
int Player::returnChips()
{
return(playerChips);
}
I've noticed that on every iteration during the original forloop, the playerList[x] value is always the same. For instance, if totalNumPlayers = 3, playerList[0], playerList[1], and playerList[2] are all effected by the setName line. Therefore, when I use cout for PL 1,2, and 3, it always prints
Player1, Player1, Player1
then
Player2, Player2, Player2
ect.
Why are the references to each index not unique to their own object?
The reason is simple. You have defined string playerName; in the global namespace (you have not given the complete structure of your source file) and therefore, whenever you invoke Player::setname, you modify this global variable and as a result, when you invoke Player::printName() in your for loop, you just read this variable that is shared among all instances of Player. To fix this, move this variable into the Player class:
class Player
{
private:
string playerName;
public:
Player();
void setname(string var);
string returnName();
string Player::returnName();
void printName();
void addChips(int x);
void printName();
// and the rest of your declarations
};
I'm working on a project where I use a forward list and vector together and output their values. The forward list is a list of Frame objects, and the vector is a vector of Display objects. The issue is that after the creation of the objects in InsertFrame(), the values of the vector are lost and essentially become garbage. I can see in the debugger it happens right after the function ends, which leads me to believe it has to do with the variables going out of scope. Here is the main creation class
// Animation.cpp
#include <crtdbg.h>
#include <iostream>
#include <string>
#include <vector>
#include <forward_list>
using namespace std;
#include "Display.h"
#include "Frame.h"
#include "Animation.h"
#include "GPUMemoryDisplay.h"
#include "SystemMemoryDisplay.h"
void Animation::InsertFrame() {
int numDisplays; //for user input of display number
vector <Display*>v; //vector for containing display objects
int p_x; //will contain user input for pixel_x
int p_y; //will contain user input for pixel_y
int p_duration; //will contain user input for duration
int p_type ; //will contain display type as int value
char * p_name; //temp string to contain user input for name
string d_name; //will contain p_name to be passed to display constructor
string frameName; //contains user input for the frame name
string gpu_shader; //contains gpu name if gpu type is selected
int q = 0; //used to count the diplay #
//begin reading user input
cout << "Insert a Frame in the Animation\nPlease enter the Frame filename: ";
cin >> frameName;
cout << "Entering the Frame Displays (the sets of dimensions and durations) " << endl;
cout << "Please enter the number of Displays: ";
cin >> numDisplays;
//display creation loop for # of displays entered
while (numDisplays > 0) {
cout << "Please enter pixel x-width for Display #" << q << " pixel_x:";
cin >> p_x;
cout << "Please enter pixel y-width for Display #" << q << " pixel_y:";
cin >> p_y;
cout << "Please enter the duration for this Display: ";
cin >> p_duration;
cout << "Please enter the name for this Display: ";
cin >> d_name;
cout << "Please enter the type for this display (1 = SystemMemoryDisplay, 2 = GPUMemoryDisplay): ";
cin >> p_type;
p_name = new char[d_name.length() + 1]; //allocate for the size of the name entered
strcpy(p_name, d_name.c_str()); //copy string to char []
if (p_type == 2) {
//input for GPU shader
cout << "Please enter the file name of the associated GPU Shader: ";
cin >> gpu_shader;
Display *gpu_p = new GPUMemoryDisplay(p_x, p_y, p_duration, p_name, gpu_shader);
v.push_back(static_cast <Display*>(gpu_p)); //casting to a display* and pushing onto the vector
numDisplays--;
q++;
}
else {
Display *sm_p = new SystemMemoryDisplay(p_x, p_y, p_duration, p_name);
v.push_back(static_cast <Display*>(sm_p));//casting to a display* and pushing onto the vector
numDisplays--;
q++;
}
cout << "\n";
}
Frame t_frame = Frame(frameName, v); //new frame holds vector which contains displays
//check if forward list is empty
if (frames.empty()) {
cout << "\nThis is the first Frame in the list \n\n";
frames.push_front(t_frame);
}
else {
forward_list <Frame>::iterator it;
int x = 0; // used for size of current forward_list
//iterate forward list to obtain the size
for (it = frames.begin(); it != frames.end(); ++it) {
x++;
}
if (x == 1) {
it = frames.begin();
frames.insert_after(it, t_frame);
}
else {
cout << "There are " << x << " Frame(s) in the list\n" << "Please specify the position, between 0 and " << x << " to insert after : ";
cin >> x; //read in where user wants to put the frame
//iterate to desired position and insert
forward_list <Frame>::iterator it;
it = frames.begin();
while (x != 0 && it != frames.end()) {
it++;
x--;
}
frames.insert_after(it, t_frame);
}
}
}
And the header/cpp files for Frame and Display
// Frame.h
#pragma once
class Frame
{
string fileName;
vector<Display*> displays;
public:
Frame(string s, vector<Display*> d) :fileName(s), displays(d) {}
Frame(const Frame&);
~Frame()
{
vector<Display*>::iterator it;
for (it = displays.begin(); it != displays.end(); it++)
delete *it;
}
friend ostream& operator<<(ostream&, Frame&);
};
#pragma once
// Display.h
class Display
{
protected: // accessible to derived classes
int pixel_x;
int pixel_y;
int duration;
char* name;
public:
Display(int x, int y, int duration, char* name);
Display(const Display&);
virtual ~Display() //makes class abstract, cannot be instantiated, most general class
{
if (name)
delete[]name;
}
virtual int BufferSize() = 0; // overridden function Polymorphic function
friend ostream& operator<<(ostream&, Display&);
};
// Display.cpp
#include <crtdbg.h>
#include <iostream>
#include <string>
#include <vector>
#include <forward_list>
using namespace std;
#include "Display.h"
#include "GPUMemoryDisplay.h"
Display::Display(int x, int y, int d, char* n) :pixel_x(x), pixel_y(y), duration(d), name(n) {
}
Display::Display(const Display& p) {
//copy values from p
pixel_x = p.pixel_x;
pixel_y = p.pixel_y;
duration = p.duration;
size_t len = strlen(p.name);
name = new char[len + 1];
strcpy(name, p.name);
//cout << pixel_x << pixel_y << duration << name;
}
I have two sub classes of Display called GPUMemoryDisplay and SystemMemoryDisplay, however I believe that part of the code is fine as I can see their values stored correctly in the debugger. Included below just in case.
#pragma once
// SystemMemoryDisplay.h
class SystemMemoryDisplay : public Display
{
public:
SystemMemoryDisplay(int x, int y, int duration, char* name) :Display(x, y, duration, name) {};
SystemMemoryDisplay(const SystemMemoryDisplay& RGMD) :Display(RGMD) {}
int BufferSize() { return pixel_x*pixel_y * sizeof(double); }
};
#pragma once
//GPUMemoryDisplay.h
//this is the derived class of display
class GPUMemoryDisplay : public Display
{
string shader;
public:
GPUMemoryDisplay(int x, int y, int duration, char* name, string shader) :Display(x, y, duration, name), shader(shader) {};
GPUMemoryDisplay(const GPUMemoryDisplay& RGPUMD) :shader(RGPUMD.shader), Display(RGPUMD) {}
string GetShader() { return shader; }
int BufferSize() { return pixel_x*pixel_y * sizeof(float); } //this is the overridden function from Display class
};
In summary I have a forward list of frames, each frame can contain a vector of Display objects. However when the InsertFrame() function exits, the display data is lost.
Once your stack-allocated Frame t_frame = Frame(frameName, v); objects go out of scope their destructors are called and will delete all the objects pointed by pointers stored in Frame::displays. You need to implement appropriate copy and / or move constructor and assignment operators that will transfer those pointers correctly. You should use ::std::unique_ptr to keep ownership of allocated objects instead of using raw pointers and deleting them manually and ::std::string to mange strings instead of raw pointer to char. Also putting using namespace std; in-between includes is also no good, if you are going to use it at least place it after includes.
I have the following files:
main.cpp
shop.hpp
player.hpp
With the following code in each of them:
main.ccp:
#include <iostream>
#include <cstdlib>
#include "shop.hpp"
using namespace std;
string *inventory= new string[3];
int invGold= 355;
int main(void){
shop store;
store.store();
}
shop.hpp:
#include <iostream>
#include <cstdlib>
using namespace std;
class shop{
public:
string shopOption;
string shopOptions[6]= {"Buy", "buy", "Sell", "sell", "Leave", "leave"};
string shopInv[3]= {"Sword", "Potion", "Arrows x 25"};
int shopInvAmount= sizeof(shopInv)/sizeof(shopInv[0]);
int shopPrices[3]= {250, 55, 70};
shop(){
cout << "Shopkeeper: We buy, we sell, what's your buisness?" << endl;
}
void store(void){
getline(cin,shopOption);
if(shopOption.compare(shopOptions[0]) == 0 || shopOption.compare(shopOptions[1]) == 0){
buy();
}
else if(shopOption.compare(shopOptions[2]) == 0 || shopOption.compare(shopOptions[3]) == 0){
sell();
}
else if(shopOption.compare(shopOptions[4]) == 0 || shopOption.compare(shopOptions[5]) == 0){
leave();
}
}
void buy(){
srand(time(0));
string buyQuotes[3]= {"What are you buyin', hon?", "Make it quick, I ain't got all day.", "Another day, another sell."};
int quotePick= rand() % sizeof(buyQuotes)/sizeof(buyQuotes[0]) - 1;
if (quotePick < 0){
quotePick= 0;
}
else if (quotePick > (sizeof(buyQuotes)/sizeof(buyQuotes))){
quotePick= sizeof(buyQuotes)/sizeof(buyQuotes);
}
cout << "TEST:" << sizeof(shopInv)/sizeof(shopInv[0]) << endl;
cout << buyQuotes[quotePick] << endl;
cout << "SHOP INVENTORY" << endl << "--------------" << endl;
cout << endl;
for (int i=0; i < sizeof(shopInv)/sizeof(shopInv[0]); i++){
cout << shopInv[i]<< ": " << shopPrices[i] << endl;
}
cout << endl << "What'll it be?:";
getline(cin,shopOption);
}
void sell(){
}
void leave(){
}
};
and player.hpp
class player{
public:
int playerHP= 18;
string playerInv[5] {};
int playerGold= 355;
};
Now, what i'd like to do, is that after the character selects the items they want to buy, and te amount of it, (Not programmed yet) check the price of the combined items, and see if the character has enough money on hand, and if the character buys the items, add them to the player's inventory.
But i'd like to keep the values the store uses, and everything related to the player in different class files.
Thing is, I have no idea how to pull something like that.
So, is t possible to access a class' variable from another class that is in another file althogether?
And if isn't, how would you suggest i get around this problem?
Start reading here: How does the compilation/linking process work? to get multiple files working for you. Odds are pretty good that whatever coding environment you are using will automate the process for you.
Then consider making an item class
class Item
{
public:
Item(string name, int price): mName(name), mPrice(price)
{
}
string getName()
{
return mName;
}
string getPrice()
{
return mPrice;
}
// other functions
private:
string mName;
int mPrice;
// other stuff
}
In Shop and Player, keep a list of Items
vector<Item> items;
When a Player tries to buy an item, find it in the list, ensure the Player can afford it, remove it from the Shop's list and add it to the Player's list.