I am stuck on a problem involving Polymorphism. My code keeps telling me that there is no default constructor for my class in this case I named creature, even though I did instantiate a constructor that takes a string in the creature class. I have a feeling I am missing something very small here and was hoping someone could help me with this. The code is as follows below.
class Creature
{
public:
Creature(string);
virtual void DoAction() = 0;
virtual void DrawOnScreen() = 0;
protected:
string CreatureName;
};
Creature::Creature(string pname)
{
this->CreatureName = pname;
};
class Monster : public Creature
{
Monster(string CreatureName);
void DoAction();
protected:
string CreatureName;
};
Monster::Monster(string pname)
{
this->CreatureName = pname;
};
class Player : public Creature
{
Player(string CreatureName);
void DoAction();
protected:
string CreatureName;
};
Player::Player(string pname)
{
this->CreatureName = pname;
}
class WildPig : public Creature
{
WildPig(string CreatureName);
void DoAction();
protected:
string CreatureName;
};
WildPig::WildPig(string pname)
{
this->CreatureName = pname;
}
class Dragon : public Creature
{
Dragon(string CreatureName);
void DoAction();
protected:
string CreatureName;
};
Dragon::Dragon(string pname)
{
this->CreatureName = pname;
}
I only included the classes within this snippet to keep it short and focused on where I believe the problem lies. Any help would be greatly appreciated.
Monster::Monster(string pname)
{
this->CreatureName = pname;
}
is equivalent to
Monster::Monster(string pname) : Creature()
{
this->CreatureName = pname;
}
And Creature doesn't have default constructor. You need:
Monster::Monster(string pname) : Creature(pname) {}
Related
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();
};
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;
}
So i have this part of code
class Robot
{
public: string Name;
public: explicit Robot(const string& Name) { this->Name = Name; }
public: Robot() { Name = "Robotic"; }
public: virtual ~Robot() = default;
public: virtual vector<string> GetCapabilities() = 0;
public: friend ostream& operator << (ostream&, const Robot&);
};
class TalkingRobot : virtual public Robot
{
public: explicit TalkingRobot(const string& Name) { this->Name = Name; }
public: virtual ~TalkingRobot() = default;
public: vector<string> GetCapabilities() { return { "Talking" }; }
};
class WalkingRobot : virtual public Robot
{
public: explicit WalkingRobot(const string& Name) { this->Name = Name; }
public: virtual ~WalkingRobot() = default;
public: vector<string> GetCapabilities() { return { "Walking" }; }
};
class VaxBot : public TalkingRobot, public WalkingRobot
{
public: explicit VaxBot(const string& Name):TalkingRobot(Name), WalkingRobot(Name) { this->Name = Name; }
public: virtual ~VaxBot() = default;
public: vector<string> GetCapabilities() { return { "Talking","Walking" }; }
};
They have a virtual function GetCapabilites().
Is there a way to rewrite GetCapabilites() in my VaxBot class to return all the inherited classes return values so that i dont have to explicitly write them like i did in here?
There isn't a simple one-line way in standard C++ to implement this sort of thing. For example, there is no way for a derived class to iterate over all its base classes, and call some member function in every base to collect the results, without explicitly naming all the bases/members separately.
It is possible to call the inherited functions, and collect their results into a single vector. For example;
std::vector<std::string> VaxBot::GetCapabilities()
{
std::vector<std::string> values(TalkingRobot::GetCapabilities());
std::vector<std::string> more_values(WalkingRobot::GetCapabilities());
values.insert(values.end(), more_values.begin(), more_values.end());
return values;
}
The above can be extended if you have more than two such bases. That means explicitly replicating code but, as I said in my opening paragraph, there is no way to implement this sort of machinery implicitly.
There are other problems with your code, but you haven't asked about those, so I won't address them. And, for readability, don't use the text public: on every line. Posting code that is unnecessarily unreadable is an effective way to reduce your chances of getting useful help, since it sets other people's teeth on edge.
class Robot
{
public: string Name;
public: vector<string> Capabilities;
public: explicit Robot(const string& Name) { this->Name = Name; }
public: Robot() { Name = "Robotic"; }
public: virtual ~Robot() = default;
public: vector<string> GetCapabilities() { return this->Capabilities; }
public: friend ostream& operator << (ostream&, const Robot&);
};
class TalkingRobot : virtual public Robot
{
public: explicit TalkingRobot(const string& Name) {
this->Name = Name;
this->Capabilities.push_back("Talking");
}
public: virtual ~TalkingRobot() = default;
};
class WalkingRobot : virtual public Robot
{
public: explicit WalkingRobot(const string& Name) {
this->Name = Name;
this->Capabilities.push_back("Walking");
}
public: virtual ~WalkingRobot() = default;
};
class VaxBot : public TalkingRobot, public WalkingRobot
{
public: explicit VaxBot(const string& Name):TalkingRobot(Name), WalkingRobot(Name) { this->Name = Name; }
public: virtual ~VaxBot() = default;
};
You could utilize multiple inheritance constructors to store Capabilities.
I am attempting to write a constructor using inheritance.
Why does mammal class not inherit the animal constructor ?
Also, why can't I overload it ?
PS: constructor takes 4 parameters.
Here is my code :
class animal {
public:
string name;
string diet;
float dailycalories;
float expectedlifetime;
virtual void display() {
}
virtual void calculateExpectedLifeTime() {
}
animal(string nam, string dit, float dacalo, float explife) {
expectedlifetime = 0;
nam = name;
dit = dailycalories;
dacalo = dailycalories;
explife = expectedlifetime;
}
};
class mammal: public animal {
animal(string nam, string dit, float dacalo, float explife) {
}
public:
float brainsize;
};
Here is how you call the parent constructor in the child constructor in C++:
class mammal: public animal{
mammal(string name, string dit, float dacalo,float explife, float brainsize):animal(name, dit, dacalo, explife){
this -> brainsize = brainsize;
}
public:
float brainsize;
};
Hope this answers your question
I Have two classes:
First:
class Thing {
public:
int code;
string name;
string description;
int location;
bool canCarry;
Thing(int _code, string _name, string _desc, int _loc, bool _canCarry) {
code = _code;
name = _name;
description = _desc;
location = _loc;
canCarry = _canCarry;
}
};
Second:
class Door: public Thing {
private:
bool open;
public:
int targetLocation;
Door(int _code, string _name, string _desc, int _loc, int _targetLoc) :
Thing(_code, _name, _desc, _loc, false) {
open = false;
targetLocation = _targetLoc;
}
void Use() {
open = true;
}
void Close() {
open = false;
}
bool isOpen() {
return open;
}
};
Forget private/public atributes...
I need to store some objects of base class and some objects of derived class,
something like this:
vector < Thing*> allThings;
things.push_back(new Thing(THING1, "THING1", "some thing", LOC1, true));
things.push_back(new Door(DOOR1, "DOOR1", "some door", LOC1, LOC2));
But in this case, functions Use(), Open(), and isOpen() will not be reachable because of slicing..
Do you have some suggestions, how to store these objects together without creating new structure of vector<Thing*> and vector<Door*>??
Thanks
A good solution to a problem when you need a container of objects with polymorphic behavior is a vector of unique pointers:
std::vector<std::unique_ptr<Thing>>
There would be no slicing in this situation, but you would have to figure out when it's OK to call Use(), Open(), and isOpen().
If you can move the methods from the derived class into the base, go for it; if you cannot do that because it makes no sense for a Thing to have isOpen(), consider using a more advanced solution, such as the Visitor Pattern:
class Thing;
class Door;
struct Visitor {
virtual void visitThing(Thing &t) = 0;
virtual void visitDoor(Door &d) = 0;
};
class Thing {
...
virtual void accept(Visitor &v) {
v.visitThing(*this);
}
};
class Door : public Thing {
...
virtual void accept(Visitor &v) {
v.visitDoor(*this);
}
}
Store pointers instead of instances, and declare public and protected methods as virtual in the base class(es).