Void pointer to class error - c++

class Hero
{
public:
Hero();
virtual int useAbility(){}
virtual int basicAttack(){}
int getHitPoints();
int getManaPoints();
void setHitPoints(int x);
void setManaPoints(int x);
protected:
unsigned int hitPoints;
unsigned int manaPoints;
private:
friend void printHero();
};
class Mage : public Hero
{
public:
Mage();
int useAbility();
int basicAttack();
std::string getClassName();
protected:
private:
std::string className;
};
Same for Warrior
int input;
void *actor;
cin >> input;
if(input == 1) actor = new Warrior;
if(input == 2) actor = new Mage;
printHero(actor.getClassName(),actor.getHitPoints(),actor.getManaPoints());
So i declare the pointer 'actor' , and I want it to become a pointer to a class, but apparently it does not work.
I get this error
request for member 'getClassName' in 'actor', which is of non-class type 'void*'

Warrior and Mage have the parent class person.
you want to do:
person *actor;

Related

How to set BaseClass variable from DerivedClass parameter

I have the classes Player and HumanPlayer. HumanPlayer is derived from Player.
class Player {
private:
int id;
protected:
string name;
public:
Player(int id);
~Player();
}
class HumanPlayer : public Player {
public:
HumanPlayer(int id, string name);
}
I want to make a constructor for HumanPlayer the set the Player id and name but I don't seem to figure out how to set Player::id to the HumanPlayer::id.
This is what I have worked out but gives an error
"int Player::id' is private within this context"
HumanPlayer::HumanPlayer(int id, string name) : Player(id){
this -> id = id;
this -> name = name;
}
For your understanding.
class Player {
private:
int id;
protected:
std::string name;
public:
//Base class constructor, initialize Id.
Player(int i):id(i)
{}
~Player() {}
//Test
int GetId()
{
return id;
}
std::string GetName()
{
return name;
}
};
class HumanPlayer : public Player {
public:
HumanPlayer(int i, std::string s) :Player(i) //Pass on Id base class constructor
{
name = s; //Protected variable accessible.
}
};
void main()
{
HumanPlayer hPlayer(10, "Test");
std::cout << hPlayer.GetId() << std::endl;
std::cout << hPlayer.GetName() << std::endl;
}

How to change a class to another class which derive from the same base class?

I have a base class called Animal:
class Animal {
protected:
std::string name;
int age;
int weight;
public:
Animal(const std::string& _name, int _age, int _weight):name(_name),age(_age),weight(_weight) {};
virtual void animal_cange(Animal*) = 0;
};
and from the Animal class derives two sublasses
class Dog : public Animal {
public:
Dog(const std::string& _name, int _age, int _weight) :Animal(_name, _age, _weight) {};
void animal_cange(Animal* poot) override {
this = new Cat(poot->name,poot->age,poot->weight);
}
};
and this
class Cat : public Animal {
public:
Cat(const std::string& _name, int _age, int _weight) :Animal(_name, _age, _weight) {};
void animal_cange(Animal* poot) override {
this = new Dog(name, age, weight);
}
};
I made a virtual funcion in the base class caled virtual void animal_cange(Animal*) = 0; which should change a Dog object to a Cat object if it is called with the object's already existing name, age and weight value and visa versa but it always gives me error like:
assignment to 'this' (anachronism)
a value of type "Cat *" cannot be assigned to an entity of type "Dog *"
protected member "Animal::name" (declared at line 12) is not accessible through a pointer or object
I also tried without animal_change being a virtual function like this:
class Animal {
protected:
std::string name;
int age;
int weight;
public:
Animal(const std::string& _name, int _age, int _weight):name(_name),age(_age),weight(_weight) {};
};
class Dog : public Animal {
public:
Dog(const std::string& _name, int _age, int _weight) :Animal(_name, _age, _weight) {};
void animal_cange() {
this = new Cat(this->name,this->age,this->weight);
}
};
class Cat : public Animal {
public:
Cat(const std::string& _name, int _age, int _weight) :Animal(_name, _age, _weight) {};
void animal_cange() {
*this = new Dog(name, age, weight);
}
};
And the erorrs i get:
this = new Cat(this->name,this->age,this->weight); : "assignment to 'this' (anachronism)" and the entity error
"no operator matches these operands operand types are: Cat = Dog *"
In general, you cannot assign an object to one of a different class - that's what static type system is about. To "change" the dynamic type of a polymorphic object the client code can create another one like this:
Animal* animal = new Dog{}; // actually you should use smart pointers
if (want_to_change) {
delete animal; // prevents a memory leak; smart pointers perform it automatically
animal = new Cat{};
}
If you would like actual animal type choice to happen during initialization, consider using a factory:
class Factory {
public:
// may be static if uses no state, than you can just write a free function
Animal* produce(/* some parameters */) const;
};
Animal* Factory::produce(/* some parameters */) const {
if (should_be_cat(/* depending on the parameters */)) {
return new Cat{};
} else {
return new Dog{};
}
}

Cannot access memory at address 0x1

I have three base Classes {Player,Weapon,Game} and one inherited Class Warrior from Player. The code I added may not be minimal but I added anything that can be relevant. Since I didn't know where to look.
This is my test for simple debugging, I add Players into vectorPlayers which is definded in game.h
int main() {
Weapon w1("hello",STRENGTH,3);
Game game(3);
game.addWarrior("s22","we",STRENGTH,3,55);
//4
game.addWarrior("s22","we",STRENGTH,3,55);
return 0;
}
When I reach the the 4th line, vectorPlayers[0] includes the correct inputs. But when I enter to game.cpp and call the function addPlayer in addWarrior,suddenly players_name for example switches to
error: Cannot access memory at address 0x1
//inside game.cpp
GameStatus Game::addPlayer(const string playerName, const string weaponName,
Target target,int hit_strength)
{
Weapon newWeapon(weaponName,target,hit_strength);
Warrior newWarrior(playerName,newWeapon,false);
if(ifNameAlreadyExists(playerName)) {
addRegPlayer(static_cast<Player*>(&newWarrior));
}
return SUCCESS;
}
GameStatus Game::addRegPlayer(Player* player)
{
playersVector.push_back(player);
}
//base classes
class Game {
private:
int maxPlayer;
vector<Player*> playersVector;
}
class Player {
string player_name;
int level;
int strength;
Weapon player_weapon;
protected:
int place;
int life;
public:
Player(const string &name, const Weapon &weapon);
virtual ~Player();
}
//inherited class
class Warrior : public Player {
private:
bool rider;
public:
Warrior ();
Warrior (string const& name, Weapon const& weapon, bool rider);
~ Warrior () override = default;
Warrior &operator=(const Warrior &warrior) ;
Warrior ( const Warrior &warrior) = default;
void makeStep() override;
};
//Constructor of Warrior
Warrior::Warrior(string const& name, Weapon const& weapon, bool rider) :
Player(name,weapon),rider(rider){
if (weapon.getTarget() == LEVEL){
throw IllegalWeapon();
}
}
//constructor of player
Player::Player(const string& name, const Weapon& weapon) :
level(1),life(1),strength(1),player_weapon(weapon),player_name(name),place(0){
}

priority_queue with abstract class

I need to create a priority_queue with abstract class "Organism" as a stored type, because I want both "Animals" and "Plants" in this queue (they derive from "Organism") but I'm not quite sure how can I do this. I've already looked for an answer but unfortunately couldn't find one that worked. Part of my code so far looks like this:
World.h:
class World
{
protected:
std::string name;
std::priority_queue<Organism, std::vector<Organism>, Compare> organisms;
public:
World(std::string name);
~World();
virtual void AddOrganism(Organism& organisms);
void EndTurn();
void DrawWorld();
};
Compare.h:
class Organism;
class Compare
{
public:
virtual bool operator()(const Organism& O1, const Organism& O2) const;
};
Organism.h:
class World;
class Organism
{
protected:
int strength, initiative, xPos, yPos, age;
World* world;
friend class Compare;
public:
virtual void Move() = 0;
virtual void Action() = 0;
virtual void Collision() = 0;
virtual void DrawMe() = 0;
};
and main:
int main()
{
SetConsoleTitle(TEXT("xxx"));
World world("World1");
Animals animal;
world.AddOrganism(animal);
system("cls");
return 0;
}
and AddOrganism method:
void World::AddOrganism(Organism& organism) {
organisms.push(organism);
};
When I try to compile this I get "Error C2259 'Organism': cannot instantiate abstract class ", anybody knows how to solve this problem?

Defining an Array of type Class

I'm trying to define an array of type Class, for my homework. The classB and classC is defined inside another classA, and I have to define the an Array which
is defined inside classC of type classB. Below is the code I'm writing.
//main.cpp
...
//cop.h
class cop
{
public:
....
class Person
{
private:
static char name;
static char age;
static char gender;
};
class Station
{
public:
Station();
~Station();
private:
Person personArray[20];
protected:
void visit();
};
//cop.cpp
char cop::Person::name;
char cop::Person::age;
char cop::Person::gender;
cop::Station::Station(){}
cop::Station::~Station(){}
Person cop::Station::personArray[20];
I get following ERROR;
'Person' does not name a type
First of all (as I'm pointing out later) the fields of Person should not be static. After that, remove the following lines:
char cop::Person::name;
char cop::Person::age;
char cop::Person::gender;
Person cop::Station::personArray[20];
Properly designed your code should read like the following:
// Person.h
class Person
{
public:
char name;
char age;
char gender;
};
// Station.h
class Station
{
public:
Station();
~Station();
private:
Person personArray[20];
protected:
void visit();
};
// Station.cpp
Station::Station()
{
for (int i = 0; i < 20; i++)
{
personArray[i].age = ...;
}
}
By the way: declaring all fields of the Person class static will definitely make sure that all persons in your array have the same name, age and gender...