priority_queue with abstract class - c++

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?

Related

Is it possible to have a virtual type in C++?

I have a class MyClass (with several virtual functions) that performs operations on an object called MyType.
The class MyClassImpl inherits MyClass and implements the virtual functions, but I need to add additional members to MyType, but I don't want to modify the class MyType (instead I want to keep it generic).
Now, if I make a MyTypeImpl and inherit MyType, I can add members. But, how do I make the non virtual functions in MyClassImpl (inherited from MyClass) use the new MyTypeImpl?
The only way I can think is to make MyClass use MyTypeImpl but I want to avoid using the implementation in the generic class because I might use various different implementations.
Here is a simple example of what the classes might look like. Of course, the code will not compile because the methods and members added in MyTypeImpl and not MyType.
class MyType {
public:
void increment() {
data_++;
}
protected:
int data_ = 0;
};
class MyClass {
public:
void alg() {
sub_routine_1();
sub_routine_2();
modify_mytype();
};
protected:
MyType mytype_;
virtual void sub_routine_1() = 0;
virtual void sub_routine_2() = 0;
void modify_mytype() {
mytype_.increment();
};
};
class MyTypeImpl : public MyType {
public:
void decrement() {
data_--;
is_decremented = true;
};
protected:
bool is_decremented = false;;
};
class MyClassImpl : public MyClass{
public:
void print() {
mytype_.print();
};
protected:
virtual void sub_routine_1() {
//do algorithm things here
mytype_.increment();
mytype_.increment();
};
virtual void sub_routine_2() {
//do more algorithm things here
mytype_.decrement();
mytype_.decrement();
};
};
After seeing your example I see now that you just want to extend the functionality of that class without modifying the original class. If you need to add additional functions, but you don't want to change the type that is stored in MyClass there isn't any way I know of to make that happen without at least modifying MyType to include virtual functions for the functions you want to call.
You also need to make MyClass take a pointer to MyType so you can use polymorphism and make the calls resolve to the correct implementation:
Dynamic Polymorphism Solution:
#include <iostream>
class MyType {
public:
virtual void increment() {
data_++;
}
// To be implemented by implementation class
virtual void print() = 0;
// To be implemented by implementation class
virtual void decrement() = 0;
protected:
int data_ = 0;
};
class MyTypeImpl : public MyType
{
public:
void print() {
std::cout << 42 << std::endl;
}
void decrement() {
data_--;
is_decremented = true;
};
protected:
bool is_decremented = false;;
};
class MyClass {
public:
MyClass(MyType* mytype)
: mytype_(mytype)
{}
void alg() {
sub_routine_1();
sub_routine_2();
modify_mytype();
};
protected:
MyType* mytype_;
virtual void sub_routine_1() = 0;
virtual void sub_routine_2() = 0;
void modify_mytype() {
mytype_->increment();
};
};
class MyClassImpl : public MyClass{
public:
MyClassImpl(MyType* mytype)
: MyClass(mytype)
{}
void print() {
mytype_->print();
};
protected:
virtual void sub_routine_1() {
//do algorithm things here
mytype_->increment();
mytype_->increment();
};
virtual void sub_routine_2() {
//do more algorithm things here
mytype_->decrement();
mytype_->decrement();
};
};
int main()
{
MyType* mytype = new MyTypeImpl();
MyClass* myclass = new MyClassImpl(mytype);
// Prints "42"
myclass->print();
// Do other stuff with "myclass"
delete myclass;
delete mytype;
}
Note, I am only using a raw pointer in this example for increased clarity. It is highly recommended that you don't use new and delete and use smart pointers to manage the lifetime of your pointers instead.
Static Polymorphism Solution:
Not that the design of this solution is actually any better, but I think this is closer to what you are actually looking for because it doesn't require modifying the MyType class directly. Also the only modification needed for MyClass is to make it a template class:
#include <iostream>
class MyType {
public:
virtual void increment() {
data_++;
}
protected:
int data_ = 0;
};
class MyTypeImpl : public MyType
{
public:
void print() {
std::cout << data_ << std::endl;
}
void decrement() {
data_--;
is_decremented = true;
};
protected:
bool is_decremented = false;
};
template <typename T>
class MyClass {
public:
void alg() {
sub_routine_1();
sub_routine_2();
modify_mytype();
};
protected:
T mytype_;
virtual void sub_routine_1() = 0;
virtual void sub_routine_2() = 0;
void modify_mytype() {
mytype_.increment();
};
};
template <typename T>
class MyClassImpl : public MyClass<T> {
public:
void print() {
this->mytype_.print();
};
protected:
virtual void sub_routine_1() {
//do algorithm things here
this->mytype_.increment();
this->mytype_.increment();
};
virtual void sub_routine_2() {
//do more algorithm things here
this->mytype_.decrement();
this->mytype_.decrement();
};
};
int main()
{
// Use the template to get the correct implementation
MyClassImpl<MyTypeImpl> myclass;
myclass.alg();
myclass.print();
// Do other stuff with my class
}

C++ error: object of abstract class type is not allowed

Having trouble with inheritance. I do not know what is wrong with the script..
in main
int main(){
Repository repo("dogs.txt");
FileAdoptionList* a = new CSVDoglist{}; / here is the error
Controller ctrl(repo, dogValidator{}, a);
UI ui(ctrl);
ui.startUI();
delete a;
}
CSVDoglist.h
class CSVDoglist : public FileAdoptionList
{
public:
void writeToFile();
void displayAdoptionlist() const;
};
FileAdoptionList.h
class FileAdoptionList : public AdoptionList
{
protected:
std::string filename;
public:
FileAdoptionList();
virtual ~FileAdoptionList() {}
void setFilename(const std::string& filename);
virtual void writeToFile() = 0;
virtual void displayAdoptionList() const = 0;
};
AdoptionList.h
class AdoptionList
{
protected:
std::vector<Dog> storage;
public:
AdoptionList();
// Adds a dog to the playlist.
void add(const Dog& dog);
// Checks if the adoptionlist is empty.
bool isEmpty();
virtual ~AdoptionList() {}
};
ERRORS:
object of abstract class type "CSVDoglist" is not allowed:
'CSVDoglist': cannot instantiate abstract class Adoptig Dogs
I have read more topics about this problem but I didn't found the solution.
Can someone help me? Thanks
It seems you have a typo.
A function named displayAdoptionlist (contains small l) is declared in CSVDoglist, but the pure virtual function displayAdoptionList (contains large L) isn't overrided in CSVDoglist.

C++ polymorphism. Methods

I have a small problem which I can't handle.
Currently I'm working over a project about a marathon between animals.
I'm obliged to use polymorphism even though it could be easier without.
Here's a sample of my code:
class Animal
{
public:
virtual void run()=0;
virtual bool return_if_finished()=0;
virtual float return_distance()=0;
}
class Turtle :public Animal
{
int id;
float distance; //etc.
public:
void run();
bool return_if_finished();
float return_distance();
void set_id(int i);
void a_friend();
}
class Snail :public Animal
{
float distance; //etc.
public:
void run();
bool return_if_finished();
float return_distance();
void broken_leg();
}
So that's a sample. All classes that inherit from the main class "Animal" have only three mutual methods. They also have some that only they do need.
If I want to write a code in a method where they "run" like that:
...
Animal* turtles = new Turtle[amount];
Animal* snails = new Snail[amount];
for(int i=0; i<amount; i++)
turtles[i].set_id(i);
I can't compile it because "class Animal has no member called "set_id"".
I could create all these methods for each class but that would be totally pointless. I bet there's a quick solution to that.
If I create a virtual void "set_id(int)" for the class "Animal" then I get the error message that not all classes that inherit from animal contain that method.
So any help would be very appreciated. Thank you
If I create a virtual void "set_id(int)" for the class "Animal" then I get the error message that not all classes that inherit from animal contain that method.
I suspect you defined Animal::set_id as a pure virtual, like this:
virtual void set_id(int) = 0;
What you really want is to define it in the Animal class as a virtual method, like this:
virtual void set_id(int _id) {id = _id};
Also, the id member variable needs to be moved to the Animal class instead of Turtle
EDIT:
Expanding the answer to include the full code:
class Animal
{
public:
Animal() : id(-1) {}
virtual ~Animal() {}
virtual void run() = 0;
virtual bool return_if_finished() = 0;
virtual float return_distance() = 0;
void set_id(int i) { id = i; }
private:
int id;
};
class Turtle :public Animal
{
public:
void run() {};
bool return_if_finished() { return true; };
float return_distance() { return 2.0; };
void a_friend() {};
};
class Snail :public Animal
{
public:
void run() {};
bool return_if_finished() { return false; };
float return_distance() { return 1.0; };
void broken_leg() {};
};
int main()
{
const int amount = 10;
Turtle turtles[amount];
Snail snails[amount];
for (int i = 0; i < amount; i++) {
turtles[i].set_id(i);
}
}
First of all, using:
Animal* turtles = new Turtle[amount];
Animal* snails = new Snail[amount];
is a bad idea.
The pointer arithmetic on turtles and snails will be based size of Animal. If you use tutles[i] for all i not equal to 0, you'll run into undefined behavior. There is probably an SO question somewhere about that.
Use a vector of pointers instead. It will be also easier to initialize them.
std::vector<Animal*> turtles(amount); = new Turtle[amount];
for(int i=0; i<amount; i++)
{
Turtle* tptr = new Turtle;
tptr->set_id(i);
turtles[i] = tptr;
}
Better yet, use a smart pointer.
std::vector<std::shared_ptr<Animal>> turtles(amount); = new Turtle[amount];
for(int i=0; i<amount; i++)
{
Turtle* tptr = new Turtle;
tptr->set_id(i);
turtles[i] = std::shared_ptr<Animal>(tptr);
// Or
// turtles[i].reset(tptr);
}

Determine type of an inherting object in c++

I have these 2 classes.
class ChessPiece
{
public:
ChessPiece();
virtual bool move() = 0;
};
class Bishop: public ChessPiece
{
public:
Bishop();
bool move();
};
I'm trying to determine the type of a ChessPiece after I created it like this
ChessPiece* foo = new Bishop()
I"m trying to get the type of foo (Bishop) not ChessPiece.
Thank You
Well, there are some ways of doing this, have a look at dynamic casting:
class A
{
public:
virtual void Foo() = 0;
};
class B : public A
{
public:
void Foo() { }
};
void Test()
{
A* bar = new B();
if (B* test = dynamic_cast<B*>(bar))
{
// use test here
}
delete bar;
}
Alternatively you can store an enum in the chess piece class defining the piece id.
One example of a way to solve your problem:
enum PieceType
{
King,
Queen,
Rook,
Bishop,
Knight,
Pawn
};
class ChessPiece
{
public:
ChessPiece();
virtual ~ChessPiece();
virtual bool move() = 0;
virtual PieceType GetType() const = 0;
};
class Bishop : public ChessPiece
{
public:
Bishop();
virtual ~Bishop();
virtual bool move();
virtual PieceType GetType() const { return Bishop; }
};
Then use ChessPiece::GetType() to determine what kind of piece this is.
You can use following code.
ChessPiece obj;
Bishop* pObj = dynamic_cast<Bishop*>(&obj);//Change to Bishop,return NULL if failed.

C++ storing base and derived class objects together

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).