C++ , variables , abstract/ virtual class - c++

Please help me, i'm pretty new to objective C++ and i do not know how to get to variable inicjatywa correctly.
I do not know what is wrong. It is possible that i do not fully understand virtual and abstract classes so i would be greatfull for explaining my mistake.
I want program to output the value of inicjatywa ( value = 5) from my object Wolf, using the pointer from Organizmy class.
class Organizmy
{
public:
int inicjatywa;
virtual void akcja() = 0;
virtual void kolizja() = 0;
virtual void rysowanie() = 0;
virtual ~Organizmy(){};
};
class Animal: public Organizmy
{
public:
int inicjatywa;
virtual void akcja() = 0;
virtual void kolizja() = 0;
virtual void rysowanie() = 0;
virtual ~Animal(){};
};
class Wolf: public Animal
{
public:
int inicjatywa;
Wolf(){
cout << "Crate Wolf" << endl;
this->inicjatywa = 5;
};
~Wolf(){};
void akcja(){};
void kolizja(){};
void rysowanie(){
cout << "W" << endl;
cout << this->inicjatywa << endl; // here he output 5
};
};
int main()
{
Organizmy *b; // I create new poiter; type Organizmy
b=new Wolf(); // He is now pointing new object Wolf
b->rysowanie(); // here he outputs correct value of the new elemnt
cout<<b->inicjatywa<< endl; //but here the code outputs -8421....
//and it should be 5 not -8421....
}

A few things. First name your functions sensible things, those names are gibberish and mean nothing to anyone on here.
Second, you're error is quite simple. The "Wolf" and "Animal" class do not need to re-declare "inicjatywa," so long as they declare their inheritance of "Organizmy" to be public (as they have) the 'outside world' will see all the public elements of "Organizmy." The code will look like this:
class Organizmy
{
public:
int inicjatywa;
virtual void akcja() = 0;
virtual void kolizja() = 0;
virtual void rysowanie() = 0;
virtual ~Organizmy(){};
};
class Animal: public Organizmy
{
public:
virtual void akcja() = 0;
virtual void kolizja() = 0;
virtual void rysowanie() = 0;
virtual ~Animal(){};
};
class Wolf: public Animal
{
public:
Wolf(){
cout << "Crate Wolf" << endl;
inicjatywa = 5;
};
~Wolf(){};
void akcja(){};
void kolizja(){};
void rysowanie(){
cout << "W" << endl;
cout << inicjatywa << endl; // here he output 5
};
};
int main()
{
Organizmy *b; // I create new poiter; type Organizmy
b=new Wolf(); // He is now pointing new object Wolf
b->rysowanie(); // here he outputs correct value of the new elemnt
cout<<b->inicjatywa<< endl; //but here the code outputs -8421....
//and it should be 5 not -8421....
}

Related

Struggling with error message undefined reference to `Fish::Fish(std::string)'

I have this UML Diagram and I have written the code below but I am struggling with an error message
However, while compiling and linking, I got an error
/tmp/cc9oQaPX.o: In function `main':
main.cpp:(.text+0x8c): undefined reference to `Fish::Fish(std::string)'
main.cpp:(.text+0xe5): undefined reference to `Cat::Cat(std::string)'
main.cpp:(.text+0x116): undefined reference to `Fish::Fish()'
main.cpp:(.text+0x158): undefined reference to `Cat::Cat()'
collect2: error: ld returned 1 exit status
#include <iostream>
using namespace std;
class Animal // define base class
{
protected:
int legs; // base class properties
public:
Animal(int legNumbers) // set values of leg
{
legNumbers = legs; // set values of leg
}
virtual void eat() = 0; // method of base class
virtual void walk() {}; // method of base class
};
class Pet // define the pet class
{
protected:
string name; // set properties of pet class
public:
virtual string getName(); // define method
virtual string setName(string name); // set name values
virtual void play() // define play method
{
cout << " garfield is playing now." << endl; // out values
}
};
class Spider :public Animal //child class inherit base class
{
public:
Spider() :Animal(8) // spider class inherit animal class
{
cout << "animals with " << legs << " legs is walking. " << endl;
}
virtual void eat() // define virtual method
{
cout << "spider is eating now. " << endl;
}
};
class Cat :public Pet, public Animal // cat inherit two classes
{
public:
Cat(string name); // set name method
Cat();
virtual void play() // define method
{
cout << name << " is playing now. " << endl;
}
virtual void eat(); // define method here
};
class Fish : public Pet, public Animal // fish inherit two method
{
public: // define public members
Fish(string name);
Fish();
virtual void play()
{
cout << name << " is playing now. " << endl;
}
virtual void eat(); // method here
void walk()
{
cout << " Fish cannot walk " << endl; // output the values
}
};
string Pet::getName() // get name value from parent class
{
return string();
}
string Pet::setName(string name)
{
return string();
}
int main(int argc, char* argv[]) // define main method
{
Fish* f = new Fish("Jaws");
Cat* c = new Cat("Tenkir");
Animal *a = new Fish();
Animal* e = new Spider();
Pet* p = new Cat();
f->play();
c->play();
e->eat();
e->walk();
a->walk();
p->play();
return 0;
}
This is right code.
Firstly, you didn't defined the constructors for Cat an Fish
But that wasn't the only problem.
Your functions walk, eat, play need to be override. And eat() has to have a block, becuase in the base class (Animal) is deleted, like eat() = 0;
#include <iostream>
using namespace std;
class Animal // define base class
{
protected:
int legs; // base class properties
public:
Animal(int legNumbers) // set values of leg
{
legs = legNumbers; // set values of leg
}
virtual ~Animal() {}
virtual void eat() = 0; // method of base class
virtual void walk() {}; // method of base class
};
class Pet // define the pet class
{
protected:
string name; // set properties of pet class
public:
virtual string getName(); // define method
virtual void setName(string name); // set name values
virtual void play() // define play method
{
cout << " garfield is playing now." << endl; // out values
}
};
string Pet::getName() // get name value from parent class
{
return this->name;
}
void Pet::setName(string name)
{
this->name = name;
}
class Spider :public Animal //child class inherit base class
{
public:
Spider() :Animal(8) // spider class inherit animal class
{
cout << "animals with " << legs << " legs is walking. " << endl;
}
virtual void eat() // define virtual method
{
cout << "spider is eating now. " << endl;
}
};
class Cat :public Pet, public Animal // cat inherit two classes
{
public:
Cat(string name)
:Animal(4)
{
this->setName(name);
} // set name method
Cat():Animal(4){}
~Cat() override {}
virtual void play() override // define method
{
cout << name << " is playing now. " << endl;
}
virtual void eat() override {} // define method here
};
class Fish : public Pet, public Animal // fish inherit two method
{
public: // define public members
Fish(string name)
:Animal(0)
{
this->setName(name);
}
Fish():Animal(0){}
~Fish() override {}
virtual void play() override
{
cout << name << " is playing now. " << endl;
}
virtual void eat() override {} // method here
void walk() override
{
cout << " Fish cannot walk " << endl; // output the values
}
};
int main(int argc, char* argv[]) // define main method
{
Fish* f = new Fish("Jaws");
Cat* c = new Cat("Tenkir");
Animal *a = new Fish();
Animal* e = new Spider();
Pet* p = new Cat();
f->play();
c->play();
e->eat();
e->walk();
a->walk();
p->play();
return 0;
}

Default value for abstract class pointer parameter

I am trying to do something like this:
class Movement {
public:
virtual void move() = 0;
};
class Walk : public Movement {
public:
void move() { cout << "walking"; }
};
class Run : public Movement {
public:
void move() { cout << "run"; }
};
class Animal {
public:
virtual void print();
};
class Human : public Animal {
public:
void print() { cout << "Human"; }
};
class Lion : public Animal {
public:
void print() { cout << "Lion"; }
};
class Model {
Animal* animal;
Movement* movement;
public:
Model(Animal* animal = new Human(), Movement* movement = new Walk()) {
this->animal = animal;
this->movement = movement;
}
void print() {
cout << "This Model consist of one: ";
animal->print();
cout << ", which is: ";
movement->move();
}
};
int main() {
Model first = Model(), second = Model(new Lion(), new Run());
first.print();
cout << endl;
second.print();
return 0;
}
How do we set the default value for abstract class pointers & how to pass them as a parameter like that from main?
I would also prefer to be able to pass arguments from main like this only in a single line without needing to initialize before.
can anyone please help me with how do we such things in C++?
I have tried and searched a lot but no luck.
I am looking for a workaround to do something like this, in which we use an abstract classes as a parameter of other classes.
I know objects cannot be assigned to a pointer, I just don't know what to do there to fulfill my requirement, an abstract class as a parameter with a default value.
This is my latest attempt with exact code, but unfortunately with new, does anyone know how to get rid of new and achieve the desired outcome?
Note:
My actual code is quite complex, basically using an abstract class for polymorphism and pass those abstract classes as parameters to another class with default parameters, if there is ANY other way to do something similar I would really appreciate the help.
This is really a design question. In Modelclass design, you either need to decide about the object ownership, or defer the decision to the calling code. In the latter case, you cannot have default arguments (unless you want to have global constants Human and Walk, but I would not recommend it).
One way to have the default arguments is to decide that Model has exclusive ownership of Animal and Movement, and store unique_ptrs to them. Something like this:
class Model {
unique_ptr<Animal> animal;
unique_ptr<Movement> movement;
public:
Model(unique_ptr<Animal> animal = make_unique<Human>(), unique_ptr<Movement> movement = make_unique<Walk>()){
this->animal = std::move(animal);
this->movement = std::move(movement);
}
void print() {
cout << "This Model consist of one: ";
animal->print();
cout << ", which is: ";
movement->move();
}
};
int main() {
Model first/*no () here!*/, second(make_unique<Lion>(), make_unique<Run>());
first.print();
cout << endl;
second.print();
return 0;
}
I think I came up with the best solution for my situation.
#include <iostream>
#include <memory>
using namespace std;
class Movement {
public:
virtual void move() = 0;
virtual unique_ptr<Movement> movement() const = 0;
};
class Walk : public Movement {
public:
void move() { cout << "walking"; }
unique_ptr<Movement> movement() const { return make_unique<Walk>(); }
};
class Run : public Movement {
public:
void move() { cout << "run"; }
unique_ptr<Movement> movement() const { return make_unique<Run>(); }
};
class Animal {
public:
virtual void print() = 0;
virtual unique_ptr<Animal> animal() const = 0;
};
class Human : public Animal {
public:
void print() { cout << "Human"; }
unique_ptr<Animal> animal() const { return make_unique<Human>(); }
};
class Lion : public Animal {
public:
void print() { cout << "Lion"; }
unique_ptr<Animal> animal() const { return make_unique<Lion>(); }
};
class Model {
unique_ptr<Animal> animal;
unique_ptr<Movement> movement;
public:
Model(const Animal& animal = Human(), const Movement& movement = Walk()) {
this->animal = animal.animal();
this->movement = movement.movement();
}
void print() {
cout << "This Model consist of one: ";
animal->print();
cout << ", which is: ";
movement->move();
}
};
int main() {
Model first = Model(), second = Model(Lion(), Run());
first.print();
cout << endl;
second.print();
return 0;
}
Is your problem the compile error? There are multiple ways to address the compile error, but given that your question is about inheriting from abstract classes, I will focus on that.
First, as provided, your Animal class is not an abstract class. An abstract class cannot be instantiated because all its methods are pure virtual. In C++, pure virtual functions are designated by the virtual keyword prefix, and suffixed by = 0 in their definition. E.g.
...
virtual void print() = 0;
...
The following code is compilable by making your Animal class an abstract class:
#include <iostream>
using namespace std;
class Movement {
public:
virtual void move() = 0;
};
class Walk : public Movement {
public:
void move() { cout << "walking"; }
};
class Run : public Movement {
public:
void move() { cout << "run"; }
};
class Animal {
public:
virtual void print() = 0;
};
class Human : public Animal {
public:
void print() { cout << "Human"; }
};
class Lion : public Animal {
public:
void print() { cout << "Lion"; }
};
class Model {
Animal* animal;
Movement* movement;
public:
Model(Animal* animal = new Human(), Movement* movement = new Walk()) {
this->animal = animal;
this->movement = movement;
}
void print() {
cout << "This Model consist of one: ";
animal->print();
cout << ", which is: ";
movement->move();
}
};
int main() {
Model first = Model(),
second = Model(new Lion(), new Run());
first.print();
cout << endl;
second.print();
return 0;
}
Incidentally, your code can also be made compilable by providing an implementation for Animal::print(). The following code is also compilable, but Animal is not an abstract class because it provides an implementation for Animal::print() rather than suffixing it with = 0:
#include <iostream>
using namespace std;
class Movement {
public:
virtual void move() = 0;
};
class Walk : public Movement {
public:
void move() { cout << "walking"; }
};
class Run : public Movement {
public:
void move() { cout << "run"; }
};
class Animal {
public:
virtual void print() {};
};
class Human : public Animal {
public:
void print() { cout << "Human"; }
};
class Lion : public Animal {
public:
void print() { cout << "Lion"; }
};
class Model {
Animal* animal;
Movement* movement;
public:
Model(Animal* animal = new Human(), Movement* movement = new Walk()) {
this->animal = animal;
this->movement = movement;
}
void print() {
cout << "This Model consist of one: ";
animal->print();
cout << ", which is: ";
movement->move();
}
};
int main() {
Model first = Model(),
second = Model(new Lion(), new Run());
first.print();
cout << endl;
second.print();
return 0;
}
Otherwise, conceptually, what you're doing is fine and totally possible in C++: assigning a default value to a base class pointer that's in some function's argument list.
Important: As commenters have correctly pointed out, the pattern you have coded is dangerous: your interface is such that a user can optionally provide an Animal instance. The problem is: if the Model creator does, then it can be reasonably argued that he rightly owns the object. If he does not, then your constructor will create a new Animal instance, but neither does Model take ownership of the object, nor does it provide an interface by which the user can take ownership of the new Animal instance. This therefore creates a memory leak. Equally, the code hazard, is ambiguous ownership of the Animal instance used in the Model constructor.

Copied object changes attributes from the base class pointer it used to copy

Consider the following classes:
class Base {
public:
... // include virtual destructor and rest of methods
virtual void changeField(int val) = 0;
virtual Base * clone() const = 0;
};
class Derived: public Base {
int x;
public:
... // include its destructor and rest of its methods
void changeField(int val) { x = val; }
Derived * clone() const { return new Derived(*this); }
};
Suppose I have an existing Base * pointer bp that points to an Derived object. Then I call bp->clone() to make a copy and store the pointer of the resulting object in a Base * pointer, copyPointer.
When I try to changeField on the copyPointer, the value is changed, but the original object has its field also changed. Why is this? And what can I do to prevent this? Would I have to create an entirely new object from scratch?
Edit: Here is my main function in which I implement the described scenario
int main() {
try {
Base * copyPointer = bp->clone();
copyPointer->changeField(5);
cout << copyPointer->print() << endl; //prints the field of Derived
delete copyPointer;
}
catch (exception& e) { // I also have an Exception class in my code
cout << e.what() << endl;
}
}
Your assumption, that the function changeField() on the copyPointer changes the original object, is wrong!
I elaborated your example:
#include <iostream>
using std::cout;
using std::endl;
class Base {
public:
// include virtual destructor and rest of methods
virtual void changeField(int val) = 0;
virtual Base * clone() const = 0;
virtual int print() const =0;
};
class Derived: public Base {
int x;
public:
// include its destructor and rest of its methods
Derived(int i):x(i) {}
void changeField(int val) { x = val; }
Derived * clone() const { return new Derived(*this); }
int print()const { return x; }
};
int main() {
Base* bp =new Derived(3);
cout <<bp->print() <<endl;
Base * copyPointer = bp->clone();
copyPointer->changeField(5);
cout <<copyPointer->print() <<endl; //prints the field of Derived
cout <<bp->print() <<endl;
}
and the output is:
3
5
3

C++ Visitor Pattern and Polymorphism

The following code is a simplified version of a VisitorPattern I have implemented on my project.
#include <iostream>
class AVisitor {
public:
virtual void visit(class A *) = 0;
};
class ExtendedVisitor : public AVisitor {
public:
virtual void visit(class B *) = 0;
};
class A {
public:
virtual void accept(AVisitor *visitor) {
std::cout << "Call accept of A" << std::endl;
visitor->visit(this);
}
};
class B : public A {
public:
void accept(AVisitor *visitor) override {
std::cout << "Call accept of B" << std::endl;
B *just_this = this;
visitor->visit(just_this); //why this calls to visit(A*)
visitor->visit((B*) just_this); //useless casting
}
};
class ActualVisitor : public ExtendedVisitor {
public:
void visit(A *x) override {
std::cout << "Call visit on A*" << std::endl;
}
void visit(B *x) override {
std::cout << "Never called" << std::endl;
}
};
int main() {
ActualVisitor visitor;
A *a = new B();
a->accept(&visitor);
}
I don't understand why the accept method of class B calls to the visitor(A*) method instead of visitor(B*). The main function prints
Call accept of B
Call visit on A*
Call visit on A*
Instead, the following code behaves as I expected:
#include <iostream>
class AVisitor {
public:
virtual void visit(class A *) = 0;
virtual void visit(class B *) = 0;
};
class A {
public:
virtual void accept(AVisitor *visitor) {
std::cout << "Call accept of A" << std::endl;
visitor->visit(this);
}
};
class B : public A {
public:
void accept(AVisitor *visitor) override {
std::cout << "Call accept of B" << std::endl;
B *just_this = this;
visitor->visit(just_this); //now it works
visitor->visit((B*) just_this);
}
};
class ActualVisitor : public AVisitor {
public:
void visit(A *x) override {
std::cout << "Call visit on A*" << std::endl;
}
void visit(B *x) override {
std::cout << "Call visit on B*" << std::endl;
}
};
int main() {
ActualVisitor visitor;
A *a = new B();
a->accept(&visitor);
}
It now prints:
Call accept of B
Call visit on B*
Call visit on B*
The problem then seems to be the inheritance of the AVisitor class. I wonder why this happens and what is the proper way to design a VisitorPattern with "specialized" visitors (here ExtendedVisitor can also visit a B object)
Your B::accept has the following signature:
void accept(AVisitor *visitor) override;
So, let's check the interface of AVisitor. It has
virtual void visit(class A *) = 0;
and that is all it has (in your first version). It is true that ExtendedVisitor has
virtual void visit(class B *) = 0;
but that does not override the method in AVisitor. In fact, your second version can help you see why. Since
virtual void visit(class A *) = 0;
virtual void visit(class B *) = 0;
can reside together in the same class (they are overloads in your second version), then they are distinct methods in this respect.
You are implementing Visitor incorrectly. Here's the right way:
class AVisitor {
public:
virtual void visit(class A *) = 0;
virtual void visit(class B *) = 0;
// virtual void visit(class C *) = 0; etc
// a separate function for every class in your hierarchy
};
and then
class ActualVisitor : public Visitor ...
There's no need for ExtendedVisitor.
Yes AVisitor must know about every class in your hierarchy. This is the principal drawback of this pattern.

C++ function that depends on base class to obtain results on derived class

In c++ pass to a function/method a derived class, in the place of a base class and still have information about the derived class?.
Ex: Say that I have a base class: "geometry" and some other class: "shape" form where I derive "rectangle" and "circle".
double area::geometry( shape& object, int i )
{
if i = 1:
rectangle thisObject = object;
double side1 = thisObject.getheight();
double side2 = thisObject.getwidth();
if i = 2:
circle thisObject = object;
double side1 = thisObject.radius * thisObject.radius;
double side2 = 3.14;
return side1 * side2;
}
The problem is that you have to suppose that the "return side1 * side2", is a very complicated code that I don't want to repeat. So I prefer to set up the problem depending on the type of input to the function, than to overload it.
The idea is very similar to this one: Is it possible to pass derived classes by reference to a function taking base class as a parameter.
Thanks!
Edit: Tried to make the code clearer.
The usual approach would be to use polymorphism:
void func(const base& ob)
{
ob.doSomethingPolymorphic();
}
where doSomethingPolymorphic() is a virtual member function of base.
If func needs to know what type ob is when you pass it in, "you are doing it wrong". The WHOLE POINT of polymorphism is that all objects appear to be the same from an outside observer, but internally do different things. The typical example is animals:
#include <iostream>
using namespace std;
class Animal
{
public:
virtual void Say() = 0;
};
class Dog : public Animal
{
public:
void Say() { cout << "Woof Woof" << endl; }
};
class Pig : public Animal
{
public:
void Say() { cout << "All animals are equal, but pigs are "
"more equal than other animals" << endl; }
};
class Cat : public Animal
{
public:
void Say() { cout << "Meow, Meow" << endl; };
};
void AnimalTalk(Animal *a[], int size)
{
for(int i = 0; i < size; i++)
{
a[i]->Say();
}
}
int main()
{
Cat c;
Pig p;
Dog d;
Animal* list[3] = { &p, &c, &d };
AnimalTalk(list, 3);
}