C++ STL set of classes - compiler error error C2664 - c++

Newbie programmer here trying to work out his homework. I'm trying to use a STL set of classes, but the compiler complains about my code.
car.h
#include <string>
#include <iostream>
#include <time.h>
#include <set>
class Car
{
private:
std::string plateNumber;
std::string description;
std::string dateIn;
std::string timeIn;
public:
Car() {};
~Car() {};
Car(std::string plate, std::string desc)
{
plateNumber = plate;
description = desc;
};
void setPlateNumber(std::string plate) ;
std::string getPlateNumber() const;
void setDesc(std::string desc);
void setTimeDateIn() ;
std::string getTimeIn() const;
std::string getDateIn() const;
std::string getDesc() const;
friend std::ostream & operator<<(std::ostream & os, Car &c);
};
std::ostream & operator<<(std::ostream & os, Car& c)
{
os << "Plate Number: " << c.plateNumber << ", Date In: " << c.dateIn << ", " <<
`"Time in: " << c.timeIn << "Description: " << c.description << std::endl;
return os;
}
bool operator< ( const Car& lhs, const Car& rhs)
{
return ( lhs.getPlateNumber() < rhs.getPlateNumber() );
};
main.cpp
#include "stdafx.h"
#include <iostream>
#include <set>
#include <string>
#include "car.h"
void carEnters(std::set<Car> g);
void carLeaves(std::set<Car> g);
void displayContents(std::set<Car> g);
int main ()
{
char choice [80];
// initialize the sets and iterators
std::set<Car> garage;
do // Loop until user quits
{
std::cout <<
std::endl;
std::cout << "Menu:" << std::endl;
std::cout << "-----" << std::endl;
std::cout << "'1' to enter a new car, or " << std::endl;
std::cout << "'2' to exit the front car, or " << std::endl;
std::cout << "'3' to to list all the cars or." << std::endl;
std::cout << "'0' to close the garage: " << std::endl;
std::cin.getline( choice, 1, '\n');
switch ( choice[0] )
{
case '0' :
std::cout << std::endl << "Thanks for playing...\n";
break;
case '1' :
carEnters(garage);
break;
case '2' :
carLeaves(garage);
case '3' :
displayContents(garage);
break;
default:
std::cout << "I'm sorry, I didn't understand that.\n";
break;
}
} while ( choice[0] != '0' ); // Loop again if the user hasn't quit.
return 0;
}
void carEnters( std::set<Car> g)
{
// Car enters garage
std::cout << "Please enter the plate number:" << std::endl;
std::string plate;
std::cin >> plate;
std::cin.ignore();
std::set<Car>::iterator findPlate;
Car* lookup = new Car;
lookup->setPlateNumber(plate);
findPlate = g.find(*lookup);
if (findPlate != g.end()) // Add car to garage
{
Car *currentCar = new Car ;
// Set car parameters
std::cout << "Please type the entering car's description <Model, Color...
> : " << std::endl;
char desc[80];
std::cin.get(desc, 80 );
std::cin.ignore();
currentCar->setDesc(desc);
currentCar->setTimeDateIn();
currentCar->setPlateNumber(plate);
g.insert(currentCar);
}
else // Plate is already in garage set
{
std::cout << "Sorry, this car is already in the garage!" <<
std::endl;
}
}
void carLeaves( std::set<Car> g)
{
std::string plate;
std::cout << "Which plate is leaving?" << std::endl;
std::cin >> plate;
std::cin.ignore();
// Find car's plate number in the garage set
// for (findPlate=garageSet.begin(); findPlate !=garageSet.end(); findPlate++)
std::set<Car>::iterator findPlate;
Car lookup(plate,"");
findPlate = g.find(lookup);
if (findPlate != g.end())
{
// Display time in and then remove car from set of cars
std::cout << "Car out at " << (*findPlate).getDateIn() << ", " <<
(*findPlate).getTimeIn() << std::endl;
g.erase(findPlate);
}
else
{
std::cout << "Car was not found in set of Cars!" << std::endl;
}
}
// Car class function implementation
void Car::setPlateNumber(std::string p)
{
plateNumber = p;
}
std::string Car::getPlateNumber() const
{
return plateNumber;
}
void Car::setDesc(std::string d)
{
description = d;
}
void Car::setTimeDateIn()
{
char dat[9];
char tim[9];
_strdate_s(dat);
_strtime_s(tim);
dateIn=dat;
timeIn=tim;
}
std::string Car::getTimeIn() const
{
return timeIn;
}
std::string Car::getDateIn() const
{
return dateIn;
}
std::string Car::getDesc() const
{
return description;
}
// Display the car set
void displayContents(std::set <Car> garage)
{
// function displays current contents of the parking garage.
std::set <Car>::iterator carIndex;
std::cout << std::endl << "Here are all the cars parked: " << std::endl;
for (carIndex = garage.begin();
carIndex != garage.end();
++carIndex )
{
std::cout << " " << carIndex->getPlateNumber() << ", Date In: " <<
carIndex->getDateIn() << ", " << "Time In: " << carIndex->getTimeIn() << "Description:
" << carIndex->getDesc() << std::endl;
}
}
The error I get from the compiler is this:
xmemory(208): error C2664: 'Car::Car(const Car &)' : cannot convert parameter 1 from 'Car *' to 'const Car &'
Reason: cannot convert from 'Car *' to 'const Car'
No constructor could take the source type, or constructor overload resolution was ambiguous
I'm not sure where I'm going wrong, would some please point out how my overload is incorrect?
Thanks

The error is likely the g.insert(currentCar) line in the carEnters method, as g is a std::set<Car>, not a std::set<Car*>. Either pass in a reference to the current car (*currentCar) or make the garage contain pointers to cars.
In addition, you may wish to pass in g as a reference, in the form of...
void carEnters(std::set<Car>& g) { }
void carLeaves(std::set<Car>& g) { }
Otherwise the set is being copied and you might not get the results you want.
If you need explanation as to the why for any of these, add a comment. I used to do some TAing back in the day. :)

I believe #James is on the right track, but passing *CurrentCar isn't really the right answer (at least IMO). Instead, you should back up a bit:
Car *currentCar = new Car ;
Perhaps you have prior experience with Java (or something similar) where this is a routine, normal type of code to write. In C++, however, using new directly is (or at least should be) fairly unusual. What you almost certainly want instead is:
Car currentCar;
and then you'll fill in the fields like:
currentCar.whatever = x;
Then, when you put your currentCar into the std::set (or whatever) you won't have to dereference anything, because you'll be starting with a Car object, which is what's expected. As an aside, I'd note that when you look up the car, you're also creating a Car object dynamically -- but you never seem to delete either one, so you're code is leaking memory.
Edit: I should add that there are alternatives that may be preferable. Right now, you're basically treating a Car as "dumb data", with outside code to operate on that data. If you want your code to be "object oriented", it would almost certainly be better to move the code for reading a Car's data into the class itself, so outside code would just invoke that member function.
Another possibility would be to make a Car an immutable object. Instead of creating an unitialized car, and then setting the appropriate values in that object, I'd pass the correct values to Car's constructor, and eliminate the member functions you currently have for changing those values. At least for your purposes, it doesn't appear that you need to actually change a car's plate number -- it should apparently only ever have one plate number, in which case it would be better for your code to reflect (and enforce) that directly.

Your problem is that your set takes elements of type Car but you are inserting elements of type Car*:
void carEnters( std::set<Car> g)
{
...
Car *currentCar = new Car;
...
g.insert(currentCar);
In this case, currentCar is a pointer to a Car and g.insert expects a Car. There are multiple ways of fixing this - you can change your set to use Car* although your overloaded operator< will no longer work (you'll have to create a functor that is passed to the set and takes two Car*s). You can change currentCar to be of type Car. This results in a bunch of copying however. Or you can ditch currentCar entirely and make a constructor that will set all the variables you need set:
Car(const std::string &plate, const std::string &desc)
{
plateNumber = plate;
description = desc;
setTimeDateIn();
};
then you can just do this:
g.insert(Car(desc, plate));
Which is actually preferable to what you are doing now, as someone might forget to call setTimeDateIn. It makes more sense for that to be called when the Car is constructed.

Related

(C++) Vector elements seem to disappear after for loop ends

I'm extremely new to C++ (even newer to OOP) and I'm doing my first project that doesn't take place within one .cpp file. I've run into a seemingly simple issue where my vector data seems to be disappearing.
Code chunk inside main.cpp's main function:
vector<Horse> HorseStable(horseAmount); // creating an vector of horse objects based on user input horseAmount
for (int i = 0; i < horseAmount; i++) // sets name for each horse and rider
{
string nameString = "";
string riderString = "";
cout << "Enter name for horse #" << (i + 1) << ": ";
cin >> nameString;
HorseStable[i].setName(nameString);
cout << "Enter name for rider of " << nameString << ": ";
cin >> riderString;
HorseStable[i].setRider(riderString);
system("cls");
}
HorseStable[0].printName(); // a test to see if the horse name stayed inside the vector (it did not)
Entire Horse.h file:
#pragma once
#include <iostream>
#include <string>
#include <stdlib.h>
#include <time.h>
class Horse
{
private:
std::string name;
std::string rider;
public:
// these three ints were supposed to be private, but I couldn't access
// maxRunningDistPerSecond as a displayHorse() function parameter from main
// maybe figuring out my first issue will help with this, as I was attempting
// HorseStable[0].displayHorse(maxRunningDistPerSecond)
int maxRunningDistPerSecond;
int distanceTraveled;
int racesWon;
Horse() // default constructor
{
std::string name = " ";
std::string rider = " ";
int maxRunningDistPerSecond = 100;
int distanceTraveled = 0;
int racesWon = 0;
};
int runASecond(int, int);
int sendToGate(int);
void displayHorse(int);
std::string setName(std::string); // sets the horse name based on user input from main.cpp variable
std::string printName(); // simply prints the horse name, I don't believe my issue is here
std::string setRider(std::string);
std::string printRider();
};
Code chunk inside Horse.cpp:
std::string Horse::setName(std::string nameString) // takes user input for horse name
{
Horse::name = nameString;
return std::string(nameString);
}
std::string Horse::printName() // prints the horse's name
{
return std::string(name);
}
setName() and getName() work perfectly within my for loop inside main.cpp, but all data seems to disappear when I attempt them after the loop ends. I've looked for hours for solutions, but had to revert to this stable build after nothing worked. I'm not very good with pointers and passing by reference, but these seem to be the only things that will work. Is it possible that I was using pointers wrong? Should I be creating a vector of Horse pointers, rather than a vector of actual Horse objects?
My other issue:
If you've noticed my public members that are supposed to be private in Horse.h, I cannot access them when private as parameters from functions called in main. This makes some sense, as my function call in main looked like this:
HorseStable[0].displayHorse(distanceTraveled)
I'm not sure how I could refer to each element of the vector within the Horse class, which seems like the only way distanceTraveled would be reachable as private. My professor wants the variables in question to be private, which makes this an issue. The user defines the amount of Horse objects, which means I can't just declare a few named Horses and simply displayHorse(distanceTraveled) them.
Function declaration from Horse.cpp:
void Horse::displayHorse(int distanceTraveled) // attempts to show a graphic of the race progress
{
if (distanceTraveled >= 50)
{
std::cout << "|-> |" << " " << name << ", ridden by " << rider;
}
else if (distanceTraveled >= 100)
{
std::cout << "|--> |" << " " << name << ", ridden by " << rider;
}
else if (distanceTraveled >= 150)
{
std::cout << "|---> |" << " " << name << ", ridden by " << rider;
} // this goes on up to 1000, but this is all that's necessary for posting
I apologize if my formatting isn't up to par, but this assignment has really been stressing me out. I've been understanding all the new material, but it always seems like pointers and referencing are the things that render my assignments unusable.

C++ beginners question how to access variables

So basicly my questions include when to use parameters and when I dont need them.
I try to learn from examples and this one I can't fully understand:
I will add the questions to the part where I dont understand something after "//" on the right side of the line.
Maybe someone can give me a good explanation, what I need to do in which scenario or good sources where I can look this up on my own.
class Student with public attributes:
#include <iostream>
class Student
{
public:
int stud_ID;
char stud_Name[22];
int stud_Age;
};
function which I want included in int main():
void studentinformation(Student); //#1Why do I must include (Student) in this fuction? ->
// If I dont add this parameter in here, there is no connection ->
//to the function studentinformation(s) in int main.
//Why exactly is that the case ?
main function to get information:
int main(){
Student s;
std::cout<<"Type in ID:";
std::cin >> s.stud_ID;
std::cout<<"Type in youre Name:";
std::cin.ignore(); //
std::cin.getline(s.stud_Name, 22); //#2 Why is std::getline(std::cin, s.stud_Name) not working ?->
std::cout<<"Type in age:"; //#3 Or is there a better alternative ?
std::cin >> s.stud_Age;
studentinformation(s); //#4 Why do I must include the parameter s ?
return 0;
}
function to print information:
void studentinformation(Student s) // #5 Why do I must include the Parameters ?
{ std::cout<<" Student information:"<< std::endl;
std::cout<<" Student ID:" << s.stud_ID << std::endl;
std::cout<<" Name:" << s.stud_Name<< std::endl;
std::cout<<" Age:" << s.stud_Age<< std::endl;
}
studentinformation() is a free function with no connection to any instance of Student which is why you need to supply one as an argument.
std::getline() works on std::strings ...
... and you'd be doing yourself a favour if you changed char stud_Name[22]; to std::string stud_Name;.
For the same reason as in 1.
For the same reason as in 1. 1, 4 and 5 are questioning the same thing.
An alternative would be to make studentinformation() a Student member function instead. You could then call s.studentinformation(); to print info about that particular student.
class Student {
public:
int stud_ID;
std::string stud_Name; // suggested change
int stud_Age;
void studentinformation() const { // const since the object (this) won't be altered
std::cout << " Student information:" << '\n';
std::cout << " Student ID:" << stud_ID << '\n';
std::cout << " Name:" << stud_Name << '\n';
std::cout << " Age:" << stud_Age << '\n';
}
};

C++ using vector iterator correctly

I'm new to C++ and I have a vector of doctors.
I add a new doctor with the following code:
void DoctorAdmin::setDoctor(std::string lastname, std::string forename,
Person::Sex sex){
//Create new doctor
Doctor* doc = new Doctor(lastname, forename, sex);
//insert at the end of the vector
doctors.push_back(doc);
}
Then I want to show their information on the console:
void DoctorAdmin::showDoctors(){
cout << "Doctors:" << endl;
cout << "Name" << "\t\t\t" << "Forename" << "\t\t\t" << "Sex" << endl;
for (vector<Doctor*>::iterator i = doctors.begin(); i != doctors.end(); i++){
Doctors* doc = doctors.at(i);
cout << doc->getName() << "\t\t\t" << doc->getForename() << "\t\t\t"
<< doc->getSex() << endl;
}
After doing it like this I get two Errors:
E0304 No instance of overloaded function "std::vector<_Ty, _Alloc>::at [mit _Ty=Doctors *, _Alloc=std::allocator<Doctors *>]" matches the argument list.
// and
C2664 "Doctors *const &std::vector<Doctors *,std::allocator<_Ty>>::at(const unsigned int) const" : cannot convert from Argument "std::_Vector_iterator<std::_Vector_val<std::_Simple_types<_Ty>>>" in "const unsigned int"
How do I use the vector iterator correctly to avoid this?
An iterator is not index-like, it is pointer-like.
for (vector<Arzt*>::iterator doc = aerzte.begin(); doc != aerzte.end(); doc++)
{
cout << (*doc)->getName() << "\t\t\t" << (*doc)->getVorname() << "\t\t\t"
<< (*doc)->getGeschlecht() << endl;
}
It seems like you are confused as to when you need to new things too. Most of the time you don't need new
vector<Arzt> aerzte;
void ArztAdmin::anlegenArzt(std::string name, std::string vorname, Person::Geschlecht geschlecht){
// Create new doctor at the end of the vector
aerzte.emplace_back(name, vorname, geschlecht);
}
You can also directly bind references as loop variables
for (Arzt & doc : aerzte)
{
cout << doc.getName() << "\t\t\t" << doc.getVorname() << "\t\t\t"
<< doc.getGeschlecht() << endl;
}
The at function requires an index, but a vector<Arzt*>::iterator is not an index, neither semantically nor technically. An iterator points directly to an element, whereas an index represents the distance between a container's start and the element in a container that allows random element access.
Because an iterator points directly to an element, the at function isn't even necessary in your loop. *i yields the element:
Arzt* doc = *i;
Beginning with C++11, the code for such simple loops can be written in a shorter way using auto:
for (auto i = aerzte.begin(); i != aerzte.end(); i++){
The compiler knows what type i really is because it knows what begin() returns.
Even better, use a range-based loop:
for (auto doc : aerzte){
cout << doc->getName() << "\t\t\t" << doc->getVorname() << "\t\t\t"
<< doc->getGeschlecht() << endl;
}
And while we're at it, don't use dynamic memory allocation when you don't have to. This isn't Java or C#; new is dangerous territory in C++ and should be avoided:
#include <vector>
#include <string>
#include <iostream>
struct Arzt
{
Arzt(std::string const& name, std::string const& vorname) :
name(name),
vorname(vorname)
{
}
std::string name;
std::string vorname;
// Geschlecht omitted for brevity's sake
};
int main()
{
std::vector<Arzt> aerzte;
Arzt doc1("foo", "bar");
Arzt doc2("foo", "bar");
Arzt doc3("foo", "bar");
aerzte.push_back(doc1);
aerzte.push_back(doc2);
aerzte.push_back(doc3);
for (auto const& arzt : aerzte)
{
std::cout << arzt.name << ' ' << arzt.vorname << '\n';
}
}
As you are no longer iterating over pointers but over larger objects, const& should be used in the for loop.

Working with Car and CarMechanic classes together, can't seem to change object's members?

So, I have two classes: Car and CarMechanic. I have declared car broken using a function of car, for the repair man to then repair it. Then I wanted the repairMan to also change the oil, to highest quality I decided would be 5 (and lowest is 1). Then I need to spray paint the car. My problem is, while repairing the car works, changing the oil and spraying the car does not. It seems like inside the function for it of the Car Mechanic's, it does set it using the set function for that variable, but then it reverses back upon exiting this function.
I am really unsure why it does this, especially since it seems to work for when the car is broken down. I tried checking over it, so if it is something stupid again, I'm sorry for wasting your time.
CarMechanic.h:
#include <iostream>
#include <string>
#include "Car.h"
using namespace std;
class CarMechanic
{
private:
string name;
public:
CarMechanic(string name); //constructor
~CarMechanic();
//class member function prototypes
void repairCar(Car &carToFix);
void oilChange(Car carToOil);
void resprayCar(Car carToSpray, string sprayColour);
};
CarMechanic.cpp:
#include "CarMechanic.h"
#include <iostream>
CarMechanic::CarMechanic(string name) //constructor
{}
CarMechanic::~CarMechanic() {} //destructor does nothing
void CarMechanic::repairCar(Car &carToFix)
{
carToFix.setBrokenDown(false); //we are setting the brokenDown private
member to false for that car, so that it gets fixed!
std::cout << "I have repaired your car." << std::endl;
}
void CarMechanic::oilChange(Car carToOil)
{
//we are saying high quality oil is 5*
carToOil.setOilQuality(5);
}
void CarMechanic::resprayCar(Car carToSpray, string sprayColour)
{
carToSpray.setColourOfCar("Green");
cout << "I have spray painted your car " << sprayColour << ". Like you
wanted." << endl;
string newColour = carToSpray.getColourOfCar();
cout << "The colour of speedster is now " << newColour << endl;
}
Car.h:
#define CAR_H
#include <string>
class Car
{ // defining the Car class
private: // restricted access, can only access from inside the class.
unsigned fuelLeft; // class member variable.
bool brokenDown = false;
int oilQuality = 0; //Oil quality goes from 1 to 5, with 5 being the highest
std::string colourOfCar = "Unknown";
public: // open access, can access from outside the class (e.g. main).
Car(); // default constructor, has no input parameters.
Car(unsigned); //int, std::string); // another constructor
~Car(); // destructor, called when car objects are destroyed.
short unsigned int fuelSpace; //irrelevant
void drive(); // irrelevant
bool hasFuel(); //irrelevant
void refuel(); //irrelevant
void breakdownNow();
void repairNow(); //irrelevant
bool isBrokenDown();
//functions set and get to change and show private bool brokenDown
bool getBrokenDown();
void setBrokenDown(bool brokenD);
//functions set and get to change and show private int oilQ
int getOilQuality();
void setOilQuality(int oilQ);
//functions set and get to change and show private string colour
std::string getColourOfCar();
void setColourOfCar(std::string colSet);
};
Car.cpp:
#include <iostream>
#include <string>
#include "Car.h"
Car::Car() {}
Car::Car(unsigned startingFuel) {...}
Car::~Car() { } // destructor does nothing.
void Car::drive() {...}
bool Car::hasFuel() {...}
void Car::refuel() {...}
void Car::breakdownNow()
{
brokenDown = true; //Car is broken
std::cout << "The beakdownNow function has set car to broken." << std::endl;
}
void Car::repairNow()
{
brokenDown = false; //Car is not broken
std::cout << "The repairNow function has set car to not broken." <<
std::endl;
}
bool Car::isBrokenDown()
{
if (brokenDown == true)
{
std::cout << "The car is broken." << std::endl;
return true;
}
else
{
std::cout << "The car isn't broken." << std::endl;
return false;
}
}
bool Car::getBrokenDown()
{
return brokenDown;
}
void Car::setBrokenDown(bool brokenD)
{
brokenDown = brokenD;
}
int Car::getOilQuality()
{
return oilQuality;
}
void Car::setOilQuality(int oilQ)
{
oilQuality = oilQ;
}
std::string Car::getColourOfCar()
{
return colourOfCar;
}
void Car::setColourOfCar(std::string colSet)
{
colourOfCar = colSet;
}
main.cpp:
//Activity 7
myCarObject1.breakdownNow(); //we need the car set to broken so that the mechanic can fix it.
CarMechanic repairMan("Mike"); //Our mechanic's called Mike.
//We need to check if the car is broken.
bool isItBroken = myCarObject1.getBrokenDown();
cout << "isItBroken is set to " << isItBroken << " for true, so it is broken." << endl;
if (isItBroken == true) //we will only repair if broken.
{
repairMan.repairCar(myCarObject1); //He will repair the car here
}
//Let us see if he really did fix the car!
isItBroken = myCarObject1.getBrokenDown();
if (isItBroken == false)
{
cout << "Looks like the car is fixed. Since isItBroken is set to " << isItBroken << " for false." << endl;
}
else
{
cout << "The car is still broken for some reason..." << endl;
}
//Activity 8
Car old1930sCar(3);
//Set the oil quality of car to low.
old1930sCar.setOilQuality(1);
//New object car with low quality oil comes to the mechanic, not good.
//Lets find out what quality of oil it has in main with getOilQuality
int oilQualityOfold1930sCar = old1930sCar.getOilQuality();
cout << "The oil quality of the old 1930's Car is " << oilQualityOfold1930sCar << "*." << endl;
//Lets use function of CarMechanic to replace this bad oil, with 5* oil.
repairMan.oilChange(old1930sCar);
oilQualityOfold1930sCar = old1930sCar.getOilQuality();
cout << "Now we have set the oil quality into the object in the class, it should be 5. It is " << oilQualityOfold1930sCar << "." << endl;
//Let us say that speedster actually wants to change the colour to Green.
repairMan.resprayCar(speedster, "Green");
//Let us confirm the repair man has turned it to green.
string newColour = speedster.getColourOfCar();
cout << "The colour of speedster is now " << newColour << endl;
The reason this is happening is because of your function definitions in CarMechanic.h and .cpp at:
void repairCar(Car &carToFix);
void oilChange(Car carToOil);
void resprayCar(Car carToSpray, string sprayColour);
Simply change the defintions to below and also respectively in the cpp files:
void repairCar(Car &carToFix);
void oilChange(Car &carToOil);
void resprayCar(Car &carToSpray, string sprayColour);
Explanation
You said that repairing the car works, changing the oil and spraying the car does not. Repairing Car works because your repairCar() method is taking the Car input paramater by reference using the "&". This means that the actual object is "referenced" from physical memory into the function. The other two functions do not pass by reference. In fact, what happens is that within those functions, the Car object is just a copy of the Car object that is passed to the function. This is known as pass by value.
Your oilChange() and resprayCar() changes do not propagate on to the carToOil and carToSpray because the changes you made are on the copy of the Car object. This copy is only local to the function, and when the function completes, these copy objects are simply destroyed.
One way to fix the issue is to pass by reference using "&" as you did in the repairCar() function. Another way is you could return the copy object in the function, i.e.
Car oilChange(Car carToOil);

C++ Can't figure out output for a class that holds player information. It outputs garbage

I've been pulling my hair out trying to figure out this program. The class has to hold 3 player's info and output their info. My output function is not outputting from my set/get functions. Also, if I output the array indexes the program crashes (that's the array indexes are commented out in the Output function).
edit: I'll just show one profile to keep the code smaller
Any help is appreciated.
#include <cstdlib>
#include <iostream>
using namespace std;
class PlayerProfile
{
public:
void output();
void setName1(string newName1); //player's name
void setPass1(string newPass1); //player's password
void setExp1(int newExp1); //player's experience
void setInv1(string newInv1[]); //player's inventory
void setPos1(int newX1, int newY1); //player's position
string getName1();
string getPass1();
int getExp1();
string getInv1();
int getPos1();
private:
string name1;
string pass1;
int exp1;
string inv1[];
int x1;
int y1;
};
int main(int argc, char *argv[])
{
PlayerProfile player;
cout << "This program generates three player objects and displays them." << endl;
cout << endl;
player.output();
system("PAUSE");
return EXIT_SUCCESS;
}
void PlayerProfile::setName1(string newName1)
{
newName1 = "Nematocyst";
name1 = newName1;
}
void PlayerProfile::setPass1(string newPass1)
{
newPass1 = "obfuscator";
pass1 = newPass1;
}
void PlayerProfile::setExp1(int newExp1)
{
newExp1 = 1098;
exp1 = newExp1;
}
void PlayerProfile::setInv1(string newInv1[])
{
newInv1[0] = "sword";
newInv1[1] = "shield";
newInv1[2] = "food";
newInv1[3] = "potion";
inv1[0] = newInv1[0];
inv1[1] = newInv1[1];
inv1[2] = newInv1[2];
inv1[3] = newInv1[3];
}
void PlayerProfile::setPos1(int newX1, int newY1)
{
newX1 = 55689;
x1 = newX1;
newY1 = 76453;
y1 = newY1;
}
string PlayerProfile::getName1()
{
return name1;
}
string PlayerProfile::getPass1()
{
return pass1;
}
int PlayerProfile::getExp1()
{
return exp1;
}
string PlayerProfile::getInv1()
{
return inv1[0], inv1[1], inv1[2], inv1[3];
}
int PlayerProfile::getPos1()
{
return x1, y1;
}
void PlayerProfile::output()
{
cout << "Player Info - " << endl;
cout << "Name: " << name1 << endl;
cout << "Password: " << pass1 << endl;
cout << "Experience: " << exp1 << endl;
cout << "Position: " << x1 << ", " << y1 << endl;
cout << "Inventory: " << endl;
/*cout << inv1[0] << endl;
cout << inv1[1] << endl;
cout << inv1[2] << endl;
cout << inv1[3] << endl; */
}
This is the output that I am getting:
This program generates three player objects and displays them.
Player Info -
Name:
Password:
Experience: -2
Position: 3353072, 1970319841
Inventory:
Press any key to continue . . .
I'm sorry if I sound like an idiot, this is the first time I have programmed with classes and I am very confused.
First:
You do not have a constructor declared or defined in your class so when you compile, the compiler provides you with a default constructor.
The line
PlayerProfile player;
calls the default constructor provided by the compiler. This default constructor only allocates memory for your class member variables, but does not set their values. This is why name1, pass1, exp1, x1, y1 are not outputting what you expect.
Second:
C++ will not call get or set functions for you, and I think you are misunderstanding how c++ functions work.
this
void PlayerProfile::setName1(string newName1)
{
name1 = newName1;
}
is a function definition. You do not need to assign newName1 inside the function. It's value is passed to the function when a line like
setName1("Nematocyst");
is executed.
If you write a constructor, you can use it to call your set functions, and pass them the values you want to set member variables to.
If you do not want to write a constructor, you can call class functions/methods from main with:
player.setName1("Nematocyst");
Third:
Your program crashes because you are not using arrays properly. Here is a tutorial on how to declare an array and access it's contents.
Generally, I think you are trying to run before you know how to walk. Try not to get frustrated. Learn how arrays work, how functions work, and then how classes work. I hope this is not your homework assignment!