I'm trying to create a simple class called 'Game' and assign some values to all three variables. However every time I run it, the values printed at the screen are completely irrelevant, and I'm pretty sure it has to do something with the class constructors but I don't know what exactly.The code is this:
#include <iostream>
#include <string>
using namespace std;
class Game
{
int id;
string name;
string winner;
public:
Game();
Game(int IDvalue, string NAMEvalue );
~Game();
void setId(int IDvalue);
void setName(string NAMEvalue);
void setWinner(string WINNERvalue);
int getId();
string getName();
string getWinner();
void status1();
};
Game::Game()
{
id = 0;
name = " ";
winner = " ";
}
Game::Game(int IDvalue, string NAMEvalue)
{
IDvalue = id;
NAMEvalue = name;
winner = " ";
}
Game::~Game()
{
}
void Game::setId(int IDvalue)
{
IDvalue = id;
}
void Game::setName(string NAMEvalue)
{
NAMEvalue = name;
}
void Game::setWinner(string WINNERvalue)
{
WINNERvalue = winner;
}
int Game::getId()
{
return id;
}
string Game::getName()
{
return name;
}
string Game::getWinner()
{
return winner;
}
void Game::status1()
{
cout << "Game's id : " << id << endl;
cout << "Game's type : " << name << endl;
cout << "Game's winner : " << winner << endl;
}
int main()
{
Game a(1, "Something");
a.setWinner("Someone");
a.status1();
return 0;
}
As you might have noticed (I'm sure you have) I'm pretty new to C++ ,so go easy on me...
Game::Game(int IDvalue, string NAMEvalue)
{
IDvalue = id;
NAMEvalue = name;
winner = " ";
}
Most of these assignments are backwards. To be consistent, the last line should have been
" " = winner;
This constructor isn't initializing id and name; instead it's assigning the (garbage) values of id and name to the parameters IDvalue and NAMEvalue, which are local variables in the function, so they're destroyed when the constructor returns and no one can see their modified values.
Fix:
Game::Game(int IDvalue, string NAMEvalue)
{
id = IDvalue;
name = NAMEvalue;
winner = " ";
}
Or better:
Game::Game(int IDvalue, string NAMEvalue)
: id(IDvalue)
, name(NAMEvalue)
, winner(" ")
{
}
By the way, your setter functions have the same problem.
You are assigning the member variables to the parameters instead of vice versa on the second constructor and set functions.
Game::Game(int IDvalue, string NAMEvalue)
{
IDvalue = id; --> id = IDvalue; OR setID(id);
NAMEvalue = name; --> name = NAMEvalue; OR setName(name);
winner = " ";
}
void Game::setId(int IDvalue)
{
IDvalue = id; --> id = IDvalue;
}
// ... the rest of the set functions
Related
So I've been learning how friendly classes work, and I created two classes, both being friendly to one another. Howewer, as soon as I write a method to modify a value in another class's field, I get a compilator error, and Visual Studio refuses to elaborate on how to fix it. Here is the code:
#include <iostream>
#include <cstring>
using namespace std;
class Human;
class Apple;
class Human
{
public:
Human();
Human(int bitepower, string& name);
void BiteApple(Apple& other)
{
other.weight -= this->bitepower;
}
void Print()
{
cout << "Имя = " << this->name << " Сила укуса = " << this->bitepower << " id = " << this->id << endl;
}
~Human();
private:
friend Apple;
int bitepower;
string name;
int id;
static int num;
};
Human::Human()
{
bitepower = 0;
num++;
id = num;
name = string("Unidentified " + id);
}
Human::Human(int test, string& name)
{
this->bitepower = test;
num++;
id = num;
this->name = name;
}
int Human::num = 0;
Human::~Human()
{
}
class Apple
{
public:
Apple();
Apple(int weight);
void Print()
{
cout << "Apple id = " << this->id << " Weight = " << this->weight << endl;
}
~Apple();
private:
friend Human;
int weight;
static int num;
int id;
};
Apple::Apple()
{
weight = 0;
num++;
id = num;
}
Apple::Apple(int weight)
{
this->weight = weight;
num++;
id = num;
}
int Apple::num = 0;
Apple::~Apple()
{
}
int main()
{
//Apple apple1(80);
//Human egor(20, "Егор");
//egor.Print();
//apple1.Print();
//egor.BiteApple(apple1);
//egor.Print();
//apple1.Print();
return 0;
}
And this is the exact method that causes everything to stop working:
void BiteApple(Apple& other)
{
other.weight -= this->bitepower;
}
After I've localised the problem, I've tried moving the announcements of the classes around, and outlining the very function to be friendly, but to no effect. I just can't seem to find the answer nowhere.
Here is the exact error I get:enter image description here
This reads as: Compilation error occured. Continue and load the last succsessfully built version?
I have also tried moving the declaration of Apple class below the declaration of Human class as suggested, but it had no effect. I would be grateful to be advised if this can be solved without creating a header file as I have not learned this yet, and if not, I'll need to learn file structure and return to friendly classes later.
I have multiple classes and each of them has their own methods. All of these methods perform the same task, as you can see in my code. The only unique thing is the values of the title, code and credit members that are defined inside the classes.
Is there a way to write this code such that a single set of methods can do the required tasks (using the specific values within the class that made the request to the method) for each and every class?
I'm a university student, and due to this I don't want to use inheritance since we haven't learned it yet.
class seng305
{
string title = "Software design and architecture", code = "SENG305";
int credit = 4;
public:
seng305();
~seng305();
string get_info();
string get_title();
int get_credit();
};
class comp219
{
string title = "Electronics in computer engineering", code = "COMP219";
int credit = 4;
public:
comp219();
~comp219();
string get_info();
string get_title();
int get_credit();
};
seng305::seng305()
{
cout << '\t' << "Created" << endl;
}
seng305::~seng305()
{
cout << '\t' << "Destroyed" << endl;
}
string seng305::get_info()
{
return (code + "-" + title);
}
string seng305::get_title()
{
return title;
}
int seng305::get_credit()
{
return credit;
}
//--------------------------------------------------
comp219::comp219()
{
cout << '\t' << "Created" << endl;
}
comp219::~comp219()
{
cout << '\t' << "Destroyed" << endl;
}
string comp219::get_info()
{
return (code + "-" + title);
}
string comp219::get_title()
{
return title;
}
int comp219::get_credit()
{
return credit;
}
As you can see, the get_info(), get_title(), and get_credit() methods do the same thing.
I would like for a single get_info(), get_title(), get_credit() to be able to do the task for each class.
There is no reason to use separate classes at all in this example. A single class will suffice, eg:
class course
{
string title, code;
int credit;
public:
course(const string &title, const string &code, int credit);
~course();
string get_info() const;
string get_title() const;
int get_credit() const;
};
course::course(const string &title, const string &code, int credit)
: title(title), code(code), credit(credit)
{
cout << '\t' << "Created" << endl;
}
course::~course()
{
cout << '\t' << "Destroyed" << endl;
}
string course::get_info() const
{
return (code + "-" + title);
}
string course::get_title() const
{
return title;
}
int course::get_credit() const
{
return credit;
}
Then, you simply create instances of your class as needed, eg:
course seng305("Software design and architecture", "SENG305", 4);
course comp219("Electronics in computer engineering", "COMP219", 4);
...
I know you said that you don't want to use inheritance, but that could be the next logical step, using the above code as a base:
class courseSeng305 : public course
{
public:
courseSeng305() : course("Software design and architecture", "SENG305", 4) {}
};
class courseComp219 : public course
{
public:
courseComp219() : course("Electronics in computer engineering", "COMP219", 4) {}
};
courseSeng305 seng305;
courseComp219 comp219;
...
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 encountering an error that says:
Invalid operands to binary expression ('ostream' (aka 'basic_ostream') and 'void')
I understand there are some questions related to this error posted on StackOverflow but I need some help and explanations regarding this specific context on what this error means.
In the main() function, I create a student object called s1. The error happens in main() where I'm trying to get the results of his GPA using a method of the Student class called getResults(double gpa).
#include <iostream>
using namespace std;
class Human{
protected: string name;
protected: int age;
public: Human(){
name = "Unknown";
age = 5;
}
public:
Human(string name, int age){
this->name = name;
this->age = age;
}
string getName(){
return name;
}
int getAge(){
return age;
}
void setName(string name){
this->name = name;
}
void setAge(int age){
this->age = age;
}
};
class Student: public Human{
protected: string school;
protected: double gpa;
public:
Student(string name, int age, string school, double gpa) : Human(name, age){
this->school = school;
this->gpa = gpa;
}
double getGPA(){
return gpa;
}
string getSchool(){
return school;
}
void setGPA(double gpa){
this->gpa = gpa;
}
void setSchool(string school){
this->school = school;
}
void getResult(double gpa){
if (gpa < 3.0) {
cout << "You did well!";
} else {
cout << "Try harder next time";
}
}
};
int main() {
Student s1 ("John", 23, 'm', "University of Chicago", 3.4);
double s1GPA = s1.getGPA();
cout << s1.getResult(s1GPA) << endl;
return 0;
}
Currently, your getResults function has a void return type, which means it doesn't actually return anything. Because of this, do not try to cout the result of this function in your main.
Consider the following edit:
// Your result is printed within this function
s1.getResult(s1GPA);
// Print a new line if you wish
cout << endl;
Also, since your getResults doesn't really get anything, I'd suggest changing the name to something like printResults.
Note
Notice how in your getResult it doesn't return anything because it's a void. In this function, you're just outputting text to the console with cout:
// Notice that this function doesn't actually return anything
void getResult(double gpa){
if (gpa < 3.0) {
// Output this message to console
cout << "You did well!";
} else {
// Output this message to console
cout << "Try harder next time";
}
}
When you have the statement in your main, it's trying to cout nothing because getResult is a void:
cout << s1.getResult(s1GPA) << endl;
// ^^^^^^^^^^^^^^^^^^^
// This doesn't return anything for cout to output.
That is why you only need to call getResult instead of trying to cout it.
Whenever I try to make an object and call a function on it, it doesn't seem to work.
I have no idea why, since I don't seem to have errors too.
I have searched around on here regarding constructors and the toString-method, but haven't find anything that worked.
I have tried to edit (distinct) the members in the constructor members,
Tried to rewrite the toString method.
Tried to make local object (with no pointer).
But it doesn't return me the things in the object that I created when calling the constructor.
Where does the problem situate in this problem?
Here is my code:
.h file:
#pragma once
#include "stdafx.h"
#include <string>
#include <sstream>
#include <iostream>
using namespace std;
class Store{
private:
int id;
string name;
string adress;
string telephone;
string btwNumber;
public:
int getId();
void setId(int);
string getName();
void setName(string);
string getAdress();
void setAdress(string);
string getTelephone();
void setTelephone(string);
string getBtwNumber();
void setBtwNumber(std::string);
string toString();
Store(int, string, string , string, string);
};
.cpp file:
// Store.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "Store.h"
Store::Store(int idnum, string nameS, string adreS, string telephonE, string btwnummeR){
idnum = id;
nameS = name;
adreS = adress;
telephonE = telephone;
btwnummeR = btwNumber;
}
int Store::getId()
{
return id;
}
void Store::setId(int id){
this->id = id;
}
string Store::getName(){
return naam;
}
void Store::setName(string name){
this->naam = naam;
}
string Store::getTelephone(){
return telephone;
}
void Store:setTelephone(string telephone){
this->telephone = telephone;
}
string Store::getBtwNumber()
{
return btwNumber;
}
void Store::setBtwNumber(string btwNumber){
btwNumber = btwNumber;
}
string Store::getAdress(){
return adress;
}
void Store::setAdress(string adress){
this->adress = adress;
}
string Store::toString(){
stringstream s;
s << "Id: " << id << endl;
s << "Naam: " << name << endl;
s << "Adres: " << adress << endl;
s << "Telefoonnummer: " << telephone << endl;
s << "BTWnummer: " << btwNumber << endl;
return s.str();
}
int _tmain(int argc, _TCHAR* argv[])
{
Store *test = new Store (4, "Test", "test", "test", "test");
test->toString();
system("Pause");
return 0;
}
Your constructor is inversed: you are assigning member variables to constructor arguments and not vice versa.
nameS = name;
Should be
name = nameS;
And so on
The method toString does work, but it won't magically decide to output its return value to screen. You'll have to do it yourself:
std::cout << test->toString() << std::endl;
You'll need to add #include <iostream> on top of your cpp file.