How to change attributes based on objects in vector? - c++

This is the situation:
a Player class with statistics as variables.
a Keeper class derived from Player.
an Action class
a Run class derived from Action
the player class has vector<Action*>
I don't understand how i can implement the following functionality:
iterate through the vector and based on the action, update the correct attribute in Player or Keeper (numberOfRunKm and numberOfSaves)
class Action {
public:
Action();
virtual ~Action();
virtual void write();
};
class Run: public Action {
double runKm;
public:
Run(double runKm);
~Run();
double getRunKm() const;
void setRunKm(double runKm);
void write();
};
class Save: public Action {
public:
Save();
~Save();
void write();
};
class Player {
string name;
vector<Action*> actions;
double numberOfRunKm = 0.0;
public:
Player(const string &name);
~Player();
virtual void write();
void run();
void addAction(Action* action);
void updateStatistics();
};
class Keeper: public Player {
int numberOfSaves = 0;
public:
Keeper(const string &name);
~Keeper();
void write();
void save();
};

Related

return single object from unique_ptr vector in c++

I'm making a command applaction I have base class that other commands class inherate.
struct BaseCommand {
public:
virtual ~BaseCommand() {}
int id = 0;
std::string name = "Base Command";
std::string description = "Base Command";
BaseCommand();
virtual std::string getName();
virtual int getId();
virtual std::string getDescription();
private:
virtual void init();
virtual void run();
};
class HelpCommand: public BaseCommand {
public:
HelpCommand();
std::string name = "help";
std::string description = "output help";
int id = 1;
virtual std::string getName();
int getId() {return this->id;};
virtual std::string getDescription();
private:
virtual void init();
virtual void run();
};
class ProductCommand: public BaseCommand {
public:
ProductCommand();
std::string name = "prod";
std::string description = "product";
int id = 2;
virtual std::string getName();
int getId() {return this->id;};
virtual std::string getDescription();
private:
virtual void init();
virtual void run();
};
and in my main, I push my subclass to a vector. my goal is to get the command by its name how do I do that and get the only command and assign it to a variable
std::vector<std::unique_ptr<BaseCommand>> commands;
// lett's push our commands...
commands.emplace_back(new HelpCommand);
commands.emplace_back(new ProductCommand);
std::string command = 'prod';
// what's the type should be for selectedCommand?
?? selectedCommand;
for (int i = 0; i < commands.size(); ++i) {
if (commands[i]->getName() == command) {
selectedCommand = commands[i];
}
}
I can't seem to determine which type should the selectedCommand be. please what I'm missing here?
I can't seem to determine which type should the selectedCommand be. please what I'm missing here?
You can't "override" member variables.
Your derived classes have two of each member variable with the same name; one in the base class and one in the derived class.
When you access the objects through a pointer to BaseCommand, you get the members from BaseCommand and not those from the dervied class.
Redesign so these are only members of the base, and make the accessors non-virtual:
struct BaseCommand {
public:
virtual ~BaseCommand() {}
const std::string& getName() const { return name; }
int getId() const { return id; }
const std::string& getDescription() const { return description; }
protected:
// Let only derived classes create base instances.
BaseCommand(int id,
const std::string& name,
const std::string& description)
: id(id), name(name), description(description)
{}
private:
int id = 0;
std::string name = "Base Command";
std::string description = "Base Command";
virtual void init();
virtual void run();
};
class HelpCommand: public BaseCommand {
public:
HelpCommand() : BaseCommand(1, "help", "output help") {}
private:
virtual void init();
virtual void run();
};
class ProductCommand: public BaseCommand {
public:
ProductCommand() : BaseCommand(2, "prod", "product") {}
private:
virtual void init();
virtual void run();
};

Call a function inside an unknown class that extends a known class

As the title says I have the following "base" class that user can extend:
class BaseScene
{
private:
bool sceneloop = false;
public:
virtual void Start();
virtual void EventHandler(SDL_Event event);
virtual void Update();
virtual void Draw();
void _toggleLoopMode() { sceneloop = !sceneloop; }
bool _sceneloop() { return sceneloop; }
};
My problem is I can't know what name, the user, choose for his classes so how I can call a known method (like Start or EventHandler) from my main class inside an unknown class?
An example of a class that is unknown to me but well-known to the user can be:
class SomeFunnyRandomName : public BaseScene
{
public:
void Start();
void Eventhandler(SDL_Event event);
void Update();
void Draw();
};
So form the main class I need to call Start() inside "SomeFunnyRandomName" without:
SomeFunnyRandomName sfrn = new SomeFunnyRandomName();
If you can include the code it will be very helpful (but not required).
You take a reference or pointer to BaseScene, and call the methods on that. The caller passes an instance of their derived class.
class UsesScene {
BaseScene & scene;
public:
UsesScene(BaseScene & scene) : scene(scene) {}
void doStuff() { scene.Start(); scene.Update(); }
/*... etc*/
};
int main() {
SomeFunnyRandomName scene;
UsesScene usesScene(scene);
usesScene.doStuff();
}

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?

C++ Polymorphism and specific methods

Given 3 classes.
class vehicle{
public:
void start();
}
class airplane: public vehicle{
void start();
void setRoute(route r);
void setAltitude(altitude a);
}
class boat: public vehicle{
void start();
void setRoute(route r);
}
Suppose we receive a parameter by command line that let us understand if we will manage an airplane or a boat.
Vehicle* v;
if (parameter == 1) {
v = new airplane();
v->setRoute(r);
v->setALtitude(a);
}
if (parameter != 1) {
v = new boat();
v->setRoute(r);
}
v->start();
Note that different methods are called for boat and airplane before start.
(Start is the only common method)
This code will not work because v doesn't contains methods setRoute/SetALtitude.
What's the correct way of implement this pattern?
You can easily do:
if(parameter != 1)
{
boat *b = new boat;
b->setRoute(r);
v = b;
}
and similar for airplane.
class __declspec(novtable) vehicle{
public:
virtual void start();
virtual void setRoute(route r) = 0;
virtual void setAltitude(altitude a) = 0;
};
class airplane: public vehicle{
virtual void start();
virtual void setRoute(route r);
virtual void setAltitude(altitude a);
};
class boat: public vehicle{
virtual void start();
virtual void setRoute(route r);
virtual void setAltitude(altitude a);
};

Inheritance and virtual function can't compile (from Head First DP)

I am new to Design Pattern, and I'm trying the first example of (Head First Design Patterns) but I'm trying to code it in C++. I can't compile my code! I don't know why. Here's my code.
#include <iostream>
using namespace std;
class QuackBehavior
{
public:
virtual void quack();
virtual ~QuackBehavior();
};
class Quack : public QuackBehavior
{
public:
void quack()
{
cout<<"Quacking"<<endl;
}
};
class MuteQuack : public QuackBehavior
{
public:
void quack()
{
cout<<"<<< Silence >>>"<<endl;
}
};
class Squeak : public QuackBehavior
{
public:
void quack()
{
cout<<"Squeak"<<endl;
}
};
class FlyBehavior
{
public:
virtual void fly();
virtual ~FlyBehavior();
};
class FlyWithWings : public FlyBehavior
{
public:
void fly()
{
cout<<"I'm flying"<<endl;
}
};
class FlyNoWay : public FlyBehavior
{
public:
void fly()
{
cout<<"I can't fly"<<endl;
}
};
class Duck
{
public:
FlyBehavior *flyBehavior;
QuackBehavior *quackBehavior;
void display();
void performFly()
{
flyBehavior->fly();
}
void performQuack()
{
quackBehavior->quack();
}
};
class MallardDuck : public Duck
{
public:
MallardDuck()
{
quackBehavior = new Quack();
flyBehavior = new FlyWithWings();
}
};
int main()
{
Duck *mallard = new MallardDuck;
cout<<"Test"<<endl;
mallard->performFly();
// mallard->performQuack();
return 0;
}
Thanks for your help.
You get a compile error because you have not provided default definitions for functions in class QuackBehavior and class FlyBehavior.
Either you could provide default implementation or make the functions pure virtual.
Make the below two changes and your code should compile fine.
class QuackBehavior
{
public:
virtual void quack(){}
virtual ~QuackBehavior(){}
};
class FlyBehavior
{
public:
virtual void fly(){}
virtual ~FlyBehavior(){}
};
OR
class FlyBehavior
{
public:
virtual void fly() = 0;
};
class QuackBehavior
{
public:
virtual void quack() = 0;
};