For some reason whenever I try running my code it always call the default constructor but it should be calling the constructor with parameters.
#include "pokemon.h"
int main()
{
int choice;
cout<<"input 1 2 or 3"<<endl;
cin>>choice;
if(choice==1||choice==2||choice==3)
{
pokemon(choice);
}
}
in my headerfile i have
#include <iostream>
#include <string>
#include <stdlib.h>
#include <time.h>
using namespace std;
class pokemon{
public:
pokemon();//default constructor
pokemon(int a);
~pokemon();//desconstructor
pokemon(const pokemon& c);
void train();
void feed();
bool isnothappy();
string getName();//accessor for the name
int getPowerlevel();//accessor for the power level
string getColor();//accessor for the color
string getType();//accessor
int getHappylevel();//accessor
static int getNumObjects();
void set_type(string);//mutator
void set_color(string);//mutator
void set_power_level(int);//mutator
void set_happy_level(int);//mutator
void set_name(string);//mutator
private:
string name;
string color;
string type;
int power_level;
int happy_level;
static int numberobject;
};
and in my other .cpp file i have
int pokemon::numberobject=0;//initialize static member variable
pokemon::pokemon(){//default constructor
name="pikachu";
color="yellow";
type="electric";
power_level=0;
happy_level=1;
cout<<"The default constructor is being called"<<endl;
++numberobject;
}
pokemon::pokemon(int a)
{
if(a==0)
{
name="Pikachu";
color="yellow";
type="electric";
power_level=1;
happy_level=1;
}
else if(a==1)
{
name="Bulbasaur";
color="green";
type="grass";
power_level=1;
happy_level=1;
}
else if(a==2)
{
name="Charmander";
color="red";
type="fire";
power_level=1;
happy_level=1;
}
else if(a==3)
{
name="Squritle";
color="blue";
type="water";
power_level=1;
happy_level=1;
}
cout<<"Congratulations you have chosen "<<getName()<<". This " <<getColor()<<" "<<getType()<<" pokemon is really quite energetic!"<<endl;
++numberobject;
}
pokemon::~pokemon()
{
//cout<<"the destructor is now being called"<<endl;
//cout<<"the number of objects before the destructor is "<<pokemon::getNumObjects()<<endl;
--numberobject;
cout<<"Now you have a total number of "<<pokemon::getNumObjects()<<endl;
}
pokemon::pokemon(const pokemon& c)//copy constructor
{
name=c.name;
color=c.color;
type=c.type;
power_level=c.power_level;
happy_level=c.happy_level;
++numberobject;
}
I have both my constructors declared and defined in my other files but this darn thing always calls the default constructor
This code:
pokemon(choice);
means the same as:
pokemon choice;
It declares a variable called choice of type pokemon, and there are no arguments given to the constructor. (You're allowed to put extra parentheses in declarations in some places).
If you meant to declare a variable where choice is a constructor argument then you have to write:
pokemon foo(choice);
If you meant to create a temporary object (which will be immediately destroyed) with choice as argument, you can write (pokemon)choice;, or pokemon(+choice);, or since C++11, pokemon{choice};.
This issue with ambiguity between declarations and non-declarations can arise any time a statement begins with a type-name followed by (. The rule is that if it is syntactically correct for a declaration then it is treated as a declaration. See most-vexing-parse for other such cases.
Related
I've been trying to learn about parametrised constructors:
Here is the program I wrote:
#include <iostream> //Using a parametrised constructor i.e. we give an integer value as a parameter
using namespace std;
class item{
int cost;
int price;
public:
item (int a){
cost=a;
}
void display(){ //Display is not a constructor, hence we need to specify its return type and parameters
cout << cost;
}
} item1;
int main(){
item1(5);
item1.display();
return 0;
}
However, I get an error on Visual Studio Code:
call of an object of a class type without appropriate operator() or conversion functions to pointer-to-function type
Can anyone tell me what's wrong with the code?
At the end of class creation you are asking to create an object named item1 but you are not providing any value, that's why it is throwing error you cannot create an object without '('.
After object creation you can't call the constructor. you can access all the methods and fields.
#include <iostream> //Using a parametrised constructor i.e. we give an integer value as a parameter
using namespace std;
class item{
int cost;
int price;
public:
item (int a){
cost=a;
}
void display(){ //Display is not a constructor, hence we need to specify its return type and parameters
cout << cost;
}
} item1(5);
int main(){
item1.display();
return 0;
}
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.
new to c++ and cant figure out why visual studio doesn't like my "HealthProfile person.setFirstName(first)" line of code. The error is with "person" and the error is no default constructor. It's probably something painfully obvious, but my code is almost identical from the code in my book. Thanks in advance!
main:
#include <iostream>
#include "HealthProfile.h"
using namespace std;
int main()
{
string first;
HealthProfile person;
cout << "Enter first name" << endl;
getline(cin,first);
person.setFirstName(first);
}
header:
#include <string>
using namespace std;
class HealthProfile
{
public:
HealthProfile(string, string, string, int, int, int, int, int);
void setFirstName(string);
string getFirstName();
void setLastName(string);
string getLastName();
};
function:
#include <iostream>
#include "HealthProfile.h"
using namespace std;
HealthProfile::HealthProfile(string first, string last, string g,
int m, int d, int y, int h, int w)
{
setFirstName(first);
setLastName(last);
setGender(g);
setMonth(m);
setDay(d);
setYear(y);
setHeight(h);
setWeight(w);
}
void HealthProfile::setFirstName(string first)
{
firstName = first;
}
string HealthProfile::getFirstName()
{
return firstName;
}
void HealthProfile::setLastName(string last)
{
lastName = last;
}
string HealthProfile::getLastName()
{
return lastName;
}
There is nothing wrong with setFirstName().
The issue is that you've declared a constructor that takes three strings and five ints, this removes the default constructor which you are using when you call HealthProfile person
The solution is to either use the HealthProfile cosntructor and pass it three strings and five ints, or to declare and define a constructor that takes no parameters by adding HealthProfile(){} to the header.
This line in main:
HealthProfile person;
Declares an instance of the HealthProfile class using a default constructor. You've not declared a default constructor. Creating your own custom constructor prevents a default constructor from being implicitly created for you. If you want to use a default constructor as well as a custom one, you need to explicitly declare and define it. If you don't want to use a default constructor, then pass in arguments to use your custom one.
To declare a default constructor in your .h:
HealthProfile();
And to define it in your .cpp:
HealthProfile::HealthProfile() { }
Or to simply call your existing custom constructor in main:
HealthProfile person(first,last,g,m,d,y,h,w); // AFTER collecting values for these arguments
i want to run the function Run in the main, but am not allowed to create object due to no default constructor. when i try to create the default constructor, i receive the message, 'Error"Game::Game int maxComponents)" provides no initialiser for:'
//Game.h
#pragma once
#include "GameComponent.h"
#include <time.h>
class Game
{
private:
int componentCount;
GameComponent** components;
const int TICKS_1000MS;
public:
Game(){} //this does not work either
Game(int maxComponents){} //this does not work as my default constructor
~Game();
void Add(GameComponent*);
void Run();
};
//Game.cpp
#pragma once
#include "StdAfx.h"
#include "Game.h"
#include <iostream>
#include<time.h>
using namespace std;
void Game::Add(GameComponent*)
{
components= new GameComponent*[componentCount];
}
void Game::Run()
{
time_t rawtime;
struct tm * timeinfo;
time ( &rawtime );
timeinfo = localtime ( &rawtime );
//cout << timeinfo->tm_hour<< ":" << timeinfo->tm_min << ":" << timeinfo->tm_sec << endl;
for(int n=0;n<componentCount;n++)
{
components[n]->Update(timeinfo);
}
}
Game::~Game()
{
}
//main.cpp
#include "stdafx.h"
#include <iostream>
#include "Game.h"
#include <time.h>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
Game obj1;
obj1.Run();
system("pause");
return 0;
}
So, how do i create a default constructor here? i've tried to use member initialising too, doesn't work. and copy constructor.
A default constructor is a constructor that takes no arguments. So, you should declare a constructor that looks something like this:
Game() { }
You can keep your other constructor - normal function overloading applies to constructors, so it will use your Game(int) constructor when you specify a single integer argument, and Game() when you specify no arguments.
However, in your case Game contains a const int member (TICKS_1000MS). Since it's const, it's expected to be initialized in the constructor. So you should do something like this:
Game() : TICKS_1000MS(123) { } // replace 123 with whatever the value should be
You need to do that for all constructors.
It's a little silly to have a non-static const member of a class which is always initialized to the same value (as opposed to a value passed in as an argument to the constructor). Consider making it an enum instead:
enum { TICKS_1000MS = 123 };
or, a static const member:
static const int TICKS_1000MS;
and initialize it in Game.cpp:
const int Game::TICKS_1000MS = 123;
As long as you have defined a constructor other than than the default one, the default constructor is not provided anymore so you have to define it manually:
public:
Game() {}
Game(int maxComponents){}
Now you have a default constructor and an overloaded constructor which takes 1 integer parameter.
You will need to create the default parameterless constructor. When you define a constructor you no longer get the default that would have been created behind the scenes.
Game(){}
The default constructor is the one that does not take any parameters, in your case Game(){}.
You do not seem to use the constructor parameter, but if you do, you will have to provide a default value.
Probably you can so something along these lines, you class Game needs to initialize const int in both the constructors:
class Game
{
private:
int componentCount;
GameComponent** components;
const int TICKS_1000MS;
public:
Game(): TICKS_1000MS(100)
{} //this does not work either
Game(int maxComponents): TICKS_1000MS(100)
{} //this does not work as my default constructor
~Game();
void Add(GameComponent*);
void Run();
};
As pointed out by others you need to intialize const data in ctor or initializer list.
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