c++ 2 Constructor 1 Object, How to? - c++

I have to set up an object and, after an user chose, i have to change some param into the object but not every each.
example:
{
class Champ
{
private:
int hp;
std::string class;
public:
Champ();
Champ(std::string chose);
};
Champ::Champ() {hp=10; class="";}
Champ::Champ(std::string chose) {class = chose;}
main()
{
Champ Test;
std::string chose;
getline(cin,chose);
Test(chose);
return 0;
}
this code give me an error.
i need hp equal for all "Champ" created but class can be changed.
The hp can't be "const" because this value may undergo changes...
how can i do this? :/

The comments in the code below should explain what is going on well enough...
#include <iostream>
#include <string>
class Champ {
int hp;
std::string job;
public:
Champ():
hp(10) { } // don't need to explicitly initialize `job` because the default constructor for string does what we want.
explicit Champ(const std::string& choose):
hp(10),
job(choose) { }
};
int main(int argc, const char * argv[]) {
using namespace std;
// this is most like how you had it with the compile error fixed.
{
Champ test; // this creates a Champ object using the default constructor
string choose;
getline(cin, choose);
test = Champ(choose); // this creates a new Champ object and assigns it to test... Throwing away the one that was created earlier.
}
// this is, imho, a better way to do it:
{
string choose;
getline(cin, choose);
auto test = Champ(choose); // declare the variable as late as possible, and after you have all the data for its construction. That way, you only make one of them.
}
return 0;
}

Related

How to make object of Parcel2 class in main function

I've separate implementation and defination of methods. Now i doesn't understand how to make object/instance of Parcel2 class in Main.cpp file. I also write in Main.cpp Parcel2::Parcel2(2); but it log saying constructor cannot call directly. kindly guide me.
Parcel2.h
#ifndef PARCEL2_H
#define PARCEL2_H
class Parcel2
{
private:
// Declare data members
int id;
public:
// Constructor
Parcel2(int id);
// Setter function
void setID(int id);
// getter function
int getID();
protected:
};
#endif
Parcel2.cpp
#include "Parcel2.h"
// Defination of constructor
Parcel2::Parcel2(int id) {
this->id = id;
}
// Defination of setter
void Parcel2::setID(int id) {
this->id = id;
}
// Defination of getter
int Parcel2::getID() {
return id;
}
Main7.cpp
#include <iostream>
#include "Parcel2.h"
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
int main(int argc, char** argv) {
// how to make object
}
If you are trying to create a Parsel2 object on the stack (as a local variable), you can just declare a variable with an integer argument. (The integer argument is needed because your constructor requires an argument.) For example:
Parcel2 obj(2);
Here is an alternative C++ 11 syntax, which some (me) find easier to parse:
auto obj = Parcel2(2);
If instead you want to dynamically allocate a Parsel2, you need to allocate it with new:
Parcel2 * obj = new Parcel2(2);
And once again, an alternative syntax:
auto obj = new Parcel2(2);
As a final note, please consider assigning class members using a member initialization list:
Parcel2::Parcel2(int id) : id(id)
{}

Error when trying to instantiate new object

I have a class AdventureGame which has a constructor. When I try to make a new AdventureGame object, I receive the error "no matching function for call to 'AdventureGame::AdventureGame()'
Here is some of my class, the constructor, and main.
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
class AdventureGame
{
private:
public:
int playerPos;
int ogrePos;
int treasurePos;
string location;
AdventureGame(int ogre, int treasure)
{
playerPos = -1;
ogrePos = ogre;
treasurePos = treasure;
location = "";
};
.
.
. // other functions that I'm sure are irrelevant
.
.
int main()
{
AdventureGame game;
int numMoves = 0;
std::string move;
while (!game.isGameOver(game.playerPos))
{
game.printDescription(game.playerPos);
cout << "Which direction would you like to move? (forward, left, or right)" << endl;
cin >> move;
game.move(move);
numMoves++;
}
}
How do I create a new game?
Your constructor expects two parameter you need to pass them.
Like this for instance:
AdventureGame game(3,5);
You should either create an empty constructor:
AdventureGame()
{
playerPos = -1;
ogrePos = 0;
treasurePos = 0;
location = "";
};
or always create your class passing ogrePos and treasurePos values to it:
AdventureGame game(0,0);
Probably it makes sense to create both empty and parameterized constructor.
You are calling a default constructor without defining it. Just calling AdventureGame game; calls a constructor function AdventureGame() {}; which is not defined. In order to call AdventureGame(int ogre, int treasure) write AdventureGame game (arg1, arg2) in the main function.
If you are using C++11 I would suggest the best practice will be always create new object with this format AdventureGame game {}. Using this format, AdventureGame game {} calls Default Constructor and AdventureGame game {arg1, arg2 ...} calls some other corresponding constructor.
Note that AdventureGame game (); DOES NOT call default constructor!!
Enjoy coding!!
Defualt Constructor is missing
AdventureGame()
{
playerPos = -1;
ogrePos = 0;
treasurePos = 0;
location = "";
}

C++ object orientated issue

I am trying to learn C++ OOP and I made the follwing code:
main.cpp
#include <iostream>
#include <string>
#include "monster.h"
using namespace std;
int main(int argc, char** argv) {
Monster monster("Wizard",150,50);
Monster monster2("Gorgoyle",450,15);
cout << monster2.getHealth() << endl;
monster.attack(monster2);
cout << monster2.getHealth() << endl;
}
monster.h
#ifndef MONSTER_H
#define MONSTER_H
#include <iostream>
#include <string>
using namespace std;
class Monster
{
public:
Monster(string name_, int health_, int damage_);
~Monster();
int attack(Monster opponet);
int getHealth();
string name;
int damage;
int health = 0;
int getDamage();
void setHealth(int health_);
void setDamage(int damage_);
void setName(string name);
void doDamageToOpponent(Monster opponent);
string getName();
};
#endif
monster.cpp
#include "monster.h"
Monster::Monster(string name_, int health_, int damage_) {
health = health_;
setDamage(damage_);
setName(name_);
}
Monster::~Monster() { }
int Monster::attack(Monster opponent) {
doDamageToOpponent(opponent);
}
void Monster::doDamageToOpponent(Monster opponent) {
int newHealth = opponent.getHealth() - this->getDamage();
opponent.setHealth(newHealth);
}
int Monster::getHealth() {
return health;
}
int Monster::getDamage() {
return damage;
}
void Monster::setHealth(int health_) {
health = health_;
}
void Monster::setDamage(int damage_) {
this->damage = damage_;
}
void Monster::setName(string name_) {
this->name = name_;
}
string Monster::getName() {
return name;
}
Now my problem is that, when I run this code I expect to have monster2 object to have 400 health left, but it is still 450 :S
What must be done here in order to to so? I noticed that it can be 400 in doDamageToOppoenet but when it leaves that block, then it is still 450. Please help me! Thanks.
You're passing objects by value:
void Monster::doDamageToOpponent(Monster opponent) <- This should be by reference
int Monster::attack(Monster opponent) <- idem
that means: you're creating a new copy of the Monster object you meant to deal damage to in the functions you're calling, and then actually dealing that copy damage but leaving the original old object with the value untouched.
Signatures as follows would work instead:
void Monster::doDamageToOpponent(Monster& opponent)
int Monster::attack(Monster& opponent)
If you want to learn more about this, something to read on: Passing stuff by reference and Passing stuff by value
The reason is that functions attack and doDamageToOpponent are taking copies of arguments, because you pass them by value. What happenes then is you change the copies of passed Monsters inside functions. After functions return, these copies die (as they are local to functions) and nothing happens to original, interested parties.
Try instead pass the argument by reference. Reference works as if it was the original variable. Consider:
int a = 0;
int &refa = a; /* refa acts as real "a", it refers to the same object "a" */
int b = a; /* this is your case */
b = 6; /* b will be changed, but "a" not */
refa = 6; /* a is changed, really "a", refa is just different name for "a" */
Try:
int Monster::attack( Monster &opponent){
doDamageToOpponent( opponent);
}
void Monster::doDamageToOpponent( Monster &opponent){
int newHealth = opponent.getHealth() - this->getDamage();
opponent.setHealth( newHealth);
}
You are passing the opponent by value, i.e., the function:
int Monster::attack(Monster opponent);
will actually receive a copy of the opponent and modify that copy. Every time you have a function that modifies some object you need to pass the object to be modified by reference or pass a pointer to it, e.g.,
int Monster::attack(Monster& opponent);
or
int Monster::attack(Monster* opponent);
I recommend using const T& for input parameters and T* for output parameters, so in this case, the latter form. The reason why I recommend the latter for output parameters is because it makes it more explicit to the caller:
monster.attack(&monster2); // passing a pointer: monster2 will be modified.

Declaring a Class C++

I am struggling knowing how to create a class. I want to create a "Player" class and all I want to do is pass in the name while I'll have the other variables start at 0 until they are updated when a game is run (later in the program)
Player::Player(string name_in)
{
name = name_in;
int numOfWins = 0;
int numOfLoses = 0;
int numOfDraws = 0;
int totalMatches = 0;
}
Right now there are lots of errors around numOfWins, numOfLoses, numOfDraws and totalMatches. What can I do to fix this?
Perhaps the error is in your int ... part of assignments, which essentially creates a new local variable in a constructor.
Try this version:
#include <string>
using namespace std;
class Player
{
string name;
int numOfWins;
int numOfLoses;
int numOfDraws;
int totalMatches;
public:
Player(string name_in)
{
name = name_in;
numOfWins = 0;
numOfLoses = 0;
numOfDraws = 0;
totalMatches = 0;
}
};
You should declare other instance variables in the class declaration, rather than declaring them as locals (which is completely useless).
// This part goes in the header
class Player {
string name;
int numOfWins;
int numOfLoses;
int numOfDraws;
int totalMatches;
public:
Player(string name_in);
};
Now in the constructor you could use initialization lists:
// This part goes into the CPP file
Player::Player(string name_in)
// Initialization list precedes the body of the constructor
: name(name_in), numOfWins(0), numOfLoses(0), numOfDraws(0), totalMatches(0) {
// In this case, the body of the constructor is empty;
// there are no local variable declarations here.
}
Kinda vague, but I'll take a crack at it. You Probably want:
class Player{
string name;
int numOfWins;
int numOfLosses;
int numOfDraws;
int totalMatches;
Player(string name_in)
};
Player::Player(string name_in){
name = name_in;
numOfWins = 0;
numOfLosses = 0;
numOfDraws = 0;
totalMatches = 0;
}
Haven't used C++ in a while, so this may be faulty.
The errors you get, at least from the snippet you posted are caused for you can't declare variables in constructor - you declare them in class body and initialize in constructor or using another function.
#include <string>
class Player {
public:
Player( std::string const& name_in) : name( name_in),
numOfWins(), numOfLoses(),
numOfDraws(), totalMatches()
{} // constructor
// will initialize variables
// numOfWins() means default
// initialization of an integer
private:
std::string name;
int numOfWins;
int numOfLoses;
int numOfDraws;
int totalMatches;
};
usage:
int main() {
Player( "player_one");
return 0;
}

How can I initialize char arrays in a constructor?

I'm having trouble declaring and initializing a char array. It always displays random characters. I created a smaller bit of code to show what I'm trying in my larger program:
class test
{
private:
char name[40];
int x;
public:
test();
void display()
{
std::cout<<name<<std::endl;
std::cin>>x;
}
};
test::test()
{
char name [] = "Standard";
}
int main()
{ test *test1 = new test;
test1->display();
}
And sorry if my formatting is bad, I can barely figure out this website let alone how to fix my code :(
If there are no particular reasons to not use std::string, do use std::string.
But if you really need to initialize that character array member, then:
#include <assert.h>
#include <iostream>
#include <string.h>
using namespace std;
class test
{
private:
char name[40];
int x;
public:
test();
void display() const
{
std::cout<<name<<std::endl;
}
};
test::test()
{
static char const nameData[] = "Standard";
assert( strlen( nameData ) < sizeof( name ) );
strcpy( name, nameData );
}
int main()
{
test().display();
}
Your constructor is not setting the member variable name, it's declaring a local variable. Once the local variable goes out of scope at the end of the constructor, it disappears. Meanwhile the member variable still isn't initialized and is filled with random garbage.
If you're going to use old-fashioned character arrays you'll also need to use an old-fashioned function like strcpy to copy into the member variable. If all you want to do is set it to an empty string you can initialize it with name[0] = 0.
Since you are using C++, I suggest using strings instead of char arrays. Otherwise you'd need to employ strcpy (or friends).
Also, you forgot to delete the test1 instance.
#include <iostream>
#include <string>
class test
{
private:
std::string name;
int x;
public:
test();
void display()
{
std::cout<<name<<std::endl;
}
};
test::test()
{
name = "Standard";
}
int main()
{
test test1;
test1.display();
std::cin>>x;
}
Considering you tagged the question as C++, you should use std::string:
#include <string>
class test
{
private:
std::string name;
int x;
public:
test();
void display()
{
std::cout<<name<<std::endl;
std::cin>>x;
}
};
test::test() : name("Standard")
{
}
c++11 actually provides two ways of doing this. You can default the member on it's declaration line or you can use the constructor initialization list.
Example of declaration line initialization:
class test1 {
char name[40] = "Standard";
public:
void display() { cout << name << endl; }
};
Example of constructor initialization:
class test2 {
char name[40];
public:
test2() : name("Standard") {};
void display() { cout << name << endl; }
};
You can see a live example of both of these here: http://ideone.com/zC8We9
My personal preference is to use the declaration line initialization because:
Where no other variables must be constructed this allows the generated default constructor to be used
Where multiple constructors are required this allows the variable to be initialized in only one place rather than in all the constructor initialization lists
Having said all this, using a char[] may be considered damaging as the generated default assignment operator, and copy/move constructors won't work. This can be solved by:
Making the member const
Using a char* (this won't work if the member will hold anything but a literal string)
In the general case std::string should be preferred