im trying to create a object called player in class player.
#include <string>
#ifndef PLAYER_HH
#define PLAYER_HH
using namespace std;
class Player
{
public:
Player(string name, int points);
const string get_name();
int get_points();
void add_points(int pts);
bool has_won();
private:
string _name;
};
#endif // PLAYER_HH
from player.cpp:
#include <string>
using namespace std;
Player::Player(string name):
_name(name), _points(0){
}
Now, the problem is, in the main function i get this error:
error: no matching function for call to ‘Player::Player(const char [6])’
Player player1 = Player("Matti");
^
Shouldn't the compiler be able to convert it to a string?
edit: Here is the full main.cpp that i'm not supposed to be changing:
#include <cstdlib>
#include <iostream>
#include <string>
#include "player.hh"
int main()
{
Player player1 = Player("Matti");
Player player2 = Player("Teppo");
Player* in_turn = 0;
int turn = 1;
while (true)
{
if (turn % 2 != 0)
{
in_turn = &player1;
}
else
{
in_turn = &player2;
}
std::cout << "Enter the score of player " << in_turn->get_name()
<< " of turn " << turn << ": ";
int pts = 0;
std::cin >> pts;
in_turn->add_points(pts);
if (in_turn->has_won())
{
std::cout << "Game over! The winner is " << in_turn->get_name() << "!" << std::endl;
return EXIT_SUCCESS;
}
std::cout << std::endl;
std::cout << "Scoreboard after turn " << turn << ":" << std::endl;
std::cout << player1.get_name() << ": " << player1.get_points() << "p" << std::endl;
std::cout << player2.get_name() << ": " << player2.get_points() << "p" << std::endl;
std::cout << std::endl;
turn += 1;
}
return EXIT_SUCCESS;
}
You guys are awesome with your fast answers :-)
You declared the constructor of player as Player(string name, int points);.
If you define a function with two parameters you have to use both.
Create your object with
Player player1 = Player("Matti", 0);
If you still want to call it with just one parameter you have to set a default value like this.
class Player
{
public:
...
Player(string name, int points = 0); // replace 0 with whatever you want to be default.
...
}
Then you can use both variants. The one above and the one you attempted
Player player1 = Player("Matti");
Of course the function header of your definition has to match the one in the declaration:
Player::Player(string name, int points):
_name(name), _points(points){
}
It's important not to write the default value inside dhe definition because this will most likely produce an compiler error.
The conversion from const char[6] to std::string will work and is not the issue here.
Your constructor has two parameters, you cannot simply omit the second one. If you like to create Player objects with a default score, declare your constructor as:
Player(string name, int points = 0);
First of all, you declare your constructor having two parameters:
Player(string name, int points);
but define it as having only one:
Player::Player(string name):
_name(name), _points(0){
}
That should give you compilation error. Either remove the second param from the declaration in class body and keep main.cpp as it is or add second param to the definition in player.cpp:
Player::Player(string name, int points):
_name(name), _points(points){
}
and then specify value for 'points' explicitly:
Player("Matti", 0);
You can also have both - just add default value for points:
class Player
{
...
Player(string name, int points = 0);
};
Then, both of these lines will work:
Player player1 ("Matti");
Player player2 ("Matti", 0);
Related
We're learning about constructors in class and I was trying to experiment with an overloaded constructor. When I run my program I keep getting an error written in the color red that says...
~
The ampersand (&) character is not allowed. The & operator is reserved for future use; wrap an ampersand in double quotation marks ("&") to pass it as part of a string.
^This only happens when I try to use private variables, when everything is public nothing goes wrong.
///Here's my code
#include <iostream>
using namespace std;
class JCole {
private:
string song;
string album;
int albumNum;
JCole::JCole(string _song, string _album, int _Num) {
song = _song;
album = _album;
albumNum = _Num;
}
};
int main() {
JCole album1("Punchin the clock", "The Off-Season", 6);
JCole album2("ATM","KOD",5);
cout << album1.song << " " << album1.album << " " << album1.albumNum << endl;
cout << album2.song << " " << album2.album << " " << album2.albumNum << endl;
return 0;
}
Your constructor is declared as private because you haven't changed the access setting.
Try this:
class JCole {
private:
string song;
string album;
int albumNum;
// Insert:
public:
JCole::JCole(string _song, string _album, int _Num) {
song = _song;
album = _album;
albumNum = _Num;
}
};
A private constructor is a nasty thing; only members of the class can call it. Thus wreaking havoc with external code that wants to instantiate this class.
Also, you can use many public:, private:, protected: within your class and in any order.
In the Test Driver.cpp file, I cannot get the getName, getStockNo, or getNoInStock to output the correct information. The set functions and the get functions for classifications and price work. I do not know how to get char from the getName function. I have attached both the CPP file and the header file. I am only having issues with the Test Driver.cpp file
//Test Driver.cpp
#include <iostream>
#include <fstream>
#include <string>
#include <cctype>
#include <string>
#include "GameRecord.h"
using namespace std;
int main()
{
// Creating the object of the GameRecord class
GameRecord gr1;
// Setting the values in the GameRecord object gr1 as per the given question
gr1.setName("VideoGame");
gr1.setStockNo(200);
gr1.setClassification(10);
gr1.setPrice(250.0);
gr1.setNoInStock(5);
//problem here
char video;
int size = 0;
gr1.getName(&video, size);
cout << "Getting Name: " << video << endl;
//problem here
long stkNo = 0;
gr1.getStockNo();
cout << "Getting Stock Number: " << stkNo << endl;
int classification;
gr1.getClassification(classification);
cout << "Getting Classification: " << classification << endl;
double price;
gr1.getPrice(price);
cout << "Getting Price: $" << price << endl;
//problem here
int NoInStock = 0;
gr1.getNoInStock();
cout << "Getting Number in Stock: " << NoInStock << endl;
// Creating another object of the GameRecord class
GameRecord gr2("VideoGame2", 100, 5, 150.0);
// To print the Gamerecord object values, call the printRecord() function
gr2.printRecord();
}
//GameRecord.cpp file
#include <iostream>
#include <string.h>
#include "GameRecord.h"
using namespace std;
// Default Constructor used to initialize the data members of the class
GameRecord::GameRecord()
{
strcpy_s(m_sName, "");
m_lStockNo = 0;
m_iClassification = 0;
m_dPrice = 0.0;
m_iCount = 0;
}
// Argumented Constructor is used to initializing the data members of the class with the
respective values GameRecord::GameRecord(const char* name, long sn, int cl, double or)
{
strcpy_s(m_sName, sizeof(m_sName), name);
m_lStockNo = sn;
m_iClassification = cl;
m_dPrice = or ;
m_iCount = 1;
}
// Destructor of the class
GameRecord::~GameRecord()
{
}
/* Getter Setter Method of the GameRecord class, Getter method is used to
get the respective values and setter is used to set the values*/
void GameRecord::getName(char* name, int nameSize)
{
strcpy_s(name, nameSize, m_sName);
}
void GameRecord::setName(const char* name)
{
strcpy_s(m_sName, sizeof(m_sName), name);
}
long GameRecord::getStockNo()
{
return m_lStockNo;
}
void GameRecord::setStockNo(long sn)
{
m_lStockNo = sn;
}
void GameRecord::getClassification(int& cl)
{
cl = m_iClassification;
}
void GameRecord::setClassification(int cl)
{
m_iClassification = cl;
}
void GameRecord::getPrice(double& c)
{
c = m_dPrice;
}
void GameRecord::setPrice(double c)
{
m_dPrice = c;
}
int GameRecord::getNoInStock()
{
return m_iCount;
}
void GameRecord::setNoInStock(int count)
{
m_iCount = count;
}
void GameRecord::printRecord()
{
cout << m_sName << " " << m_lStockNo << " " << m_iClassification << " " << m_dPrice << " "
<< m_iCount << endl;
}
//GameRecord.h file
#pragma once
#include <iostream>
#include <string.h>
using namespace std;
class GameRecord
{
private:
char m_sName[128]; // used to store the name of a videogame or videogame system.
long m_lStockNo; // used to store a unique stock number for the videogame or videogame
system int m_iClassification; // used to code specific information about the videogame or
videogame system
.double m_dPrice; // used to store the price of this videogame or videogame system
int m_iCount; // used to store the number of copies of this item currently in the
inventory.
public
: GameRecord(); // constructor set the member variables to the following initial values.
// set the member variables to the values passed into the function and initialize the
m_iCount variable to one(1).GameRecord(const char* name, long sn, int cl, double price);
~GameRecord(); //The destructor shall be an empty, place - holder function.
// copy the member variable m_sName into the character array pointed to by the function argument.
void getName(char* name, int nameSize);
// function will copy the function argument into the member variable m_sName.
void setName(const char* name);
// function shall return the value stored in the member variable m_lStockNo.
long getStockNo();
// function will copy the function argument into the member variable m_lStockNo.
void setStockNo(long sn);
// function will copy the member variable m_iClassification into the interger variable referenced by the function argument.
void getClassification(int& cl);
// function will copy the function argument into the member variable m_iClassification.
void setClassification(int cl);
// function will copy the member variable m_dPrice into the double variable pointed to by the function argument.
void getPrice(double& c);
// function will copy the function argument into the member variable m_dPrice.
void setPrice(double c);
int getNoInStock(); // function shall return the value stored in the member variable
m_iCount.
void
setNoInStock(int count); // function will copy the function argument into the member
variable m_iCount.
void
printRecord(); // shall print to the screen all data found in the record
};
the function getName should be used as
int size=...;
char*name=new char[size];
c.gerName(name,size);
because it works by copying the name to the pointer got in the input
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.
writing this program for my c++ class and im running into an issue. My program reads the inputtted name and stores it into name it then wants to check for correct parameters under _name.. here are my class and its header file.
My error is specifically under ::setName where i want to check or set my inputted name with _name for correct output under ::display()
PhoneNumber.cpp
using namespace oop244;
void PhoneNumber::display() const{
cout << "name: " << _name << ", Phone number: (" << _areacode << ") " << _localNumber / 10000 << "-" << _localNumber % 10000 << endl;
}
bool PhoneNumber::isValid() const
{
if (correctNum == false && correctArea == false){
cout << _name << " does not have a valid phone number." << endl;
return false;
}
else{
return true;
}
}
void PhoneNumber::setName(const char name[])
{
cout << name << endl;
_name = name;
}
PhoneNumber.h
#define MAX_NAME_LENGTH 40
#define PHNO_MAX 999999
#define PHNO_MIN 100000
#define AREACODE_MIN 100
#define AREACODE_MAX 999
namespace oop244{
class PhoneNumber{
private:
char _name[MAX_NAME_LENGTH + 1];
int _areacode;
int _localNumber;
bool _validPhoneNumber;
public:
void setName(const char name[]);
void setPhoneNumber(int areaCode, int number);
void display() const;
bool isValid() const;
};
};
use standard string
#include <string>
and use
std::string _name;
in your class declarations instead of
char _name[MAX_NAME_LENGTH + 1];
alternatively use c-style str-functions, as suggested in another answer
You can't assign raw arrays. You need to copy the contents.
Assuming your class teacher forces you to use char arrays, you can for example use strncpy to copy the characters:
strncpy(_name, name, MAX_NAME_LENGTH);
You need to #include <cstring> for this.
If your class teacher allows it, better use std::array<char,MAX_NAME_LENGTH> or even std::string. Both can be copied by assigning.
I am in what seems to be a never ending quest to understand pointers. I finally have a working code using pointers to create a quick character and enemy, then mock an overly simple battle. It works 100% as it seems, but I'm not 100% sure it's correct or what I did to make it right. I have read 13 chapters so far in my C++ book (2 being over pointers specifically), but I'm still not sure it's clicked. If this looks like a valid use and proper utilization of them, I think I'm getting there, just wanted some clarification if it is. Thanks in advance!
#include <iostream>
#include <string>
#ifndef CLASS_H
#define CLASS_H
class Unit
{
public:
Unit(const std::string name, int hp, int power);
~Unit();
void printHP();
void attack(Unit* unit);
bool isDead();
private:
std::string mName;
int mHP;
int mPower;
};
Unit::Unit(const std::string name, int hp, int power)
{
mName = name;
mHP = hp;
mPower = power;
}
void Unit::printHP()
{
std::cout << std::endl;
std::cout << mName << "'s HP: " << mHP << std::endl;
}
void Unit::attack(Unit* unit)
{
std::cout << std::endl;
std::cout << unit->mName << " takes " << this->mPower << " damage! " << std::endl;
unit->mHP -= this->mPower;
}
bool Unit::isDead()
{
return this->mHP < 1;
}
Unit::~Unit()
{
}
#endif
int main()
{
Unit player1("GoodFellow", 20, 5);
Unit Enemy("ABadMan", 10, 2);
while (!Enemy.isDead())
{
player1.printHP();
Enemy.printHP();
player1.attack(&Enemy);
Enemy.attack(&player1);
}
}
Modified it to this... I think I get the reason for only using a reference, just trying to get the concept of pointers....
#include <iostream>
#include <string>
#ifndef CLASS_H
#define CLASS_H
class Unit
{
public:
Unit(const std::string name, int hp, int power);
~Unit();
void printHP();
void attack(Unit& unit);
bool isDead();
void setHP(int hp);
private:
std::string mName;
int mHP;
int mPower;
};
Unit::Unit(const std::string name, int hp, int power)
{
mName = name;
mHP = hp;
mPower = power;
}
void Unit::printHP()
{
std::cout << std::endl;
std::cout << mName << "'s HP: " << mHP << std::endl;
}
void Unit::attack(Unit& unit)
{
std::cout << std::endl;
std::cout << unit.mName << " takes " << this->mPower << " damage! " << std::endl;
unit.mHP -= this->mPower;
}
bool Unit::isDead()
{
return this->mHP < 1;
}
void Unit::setHP(int hp)
{
this->mHP = hp;
}
Unit::~Unit()
{
}
#endif
int main()
{
Unit player1("GoodFellow", 20, 5);
Unit Enemy("ABadMan", 10, 2);
while (true)
{
while (!Enemy.isDead())
{
player1.printHP();
Enemy.printHP();
player1.attack(Enemy);
Enemy.attack(player1);
}
char playAgain;
std::cout << "Fight again? (y)/(n)" << std::endl;
std::cin >> playAgain;
if (playAgain == 'n')
{
break;
}
else
{
Enemy.setHP(10);
}
}
}
Yes, that's a reasonable use of pointers. I was actually glad to see that you used them very little. I was half expecting to see Unit* player1 = new Unit ... and such all over the place. But no, you used automatic storage duration all over (rather than dynamic), which was very appropriate.
So the main reason for passing Unit*s to the attack functions is to that inside the function you can modify the Unit that you're attacking and have the effect seen outside. If you were to pass the Units directly, they would be copied into the function and then the unit->mHP -= this->mPower; would only affect the copy.
However, there is a more appropriate tool at your disposal here. You can use references. A reference also allows you to pass an object without copying it, so that modifications inside the function can be seen outside. Your attack function signature would change to:
void Unit::attack(Unit& unit)
The type Unit& is a "reference to Unit". Don't confuse the use of & with taking the address of an object - it means something completely different here. You would then call it like so:
player1.attack(Enemy);
The point is you should try to avoid pointers as much as possible. Since you can use references here, which are safer (you do not need to check for null), you should use them.
It's fine to learn about how pointers to work, but in doing so, you should learn how to use other more appropriate tools for the job.