Ambiguous workaround for multiinheritance? - c++

I have a base class called animal, and a dog and a cat that inherit from Animal.
And a multiinheritance class called dogcat, that inherit from dog and cat,
in Animal i have method called sleep. When i want to use that method from dogcat, i get the error "DogCat::sleep" is ambiguous, i do understand the problem, but i read in a book that it should be possible, when you declare sleep as virtual - but it does not work.
Is this not possible is the book wrong or is there any workaround?
class Animal
{
public:
Animal(){}
virtual void sleep()
{
cout << "zzzzzzzzz" << endl;
}
virtual void eat() = 0;
};
class Dog: public Animal
{
protected:
Dog(){}
virtual void eat() override
{
cout << "eats dogfood" << endl;
}
};
class Cat :public Animal
{
public:
Cat(){}
virtual void eat() override
{
cout << "eats catfood" << endl;
}
};
class DogCat : public Dog, public Cat
{
public:
DogCat(){}
using Dog::eat;
};
int main(int argc, char** argv) {
DogCat *DC = new DogCat();
DC->sleep();//Error
}

You have the diamond problem
The "diamond problem" (sometimes referred to as the "deadly diamond of death"[4]) is an ambiguity that arises when two classes B and C inherit from A, and class D inherits from both B and C. If there is a method in A that B and C have overridden, and D does not override it, then which version of the method does D inherit: that of B, or that of C?
So. Now you have two instances of A. What is it the solution? You have two:
Define sleep operation in one of subclases and call it:
class Cat :public Animal
{
public:
Cat(){}
virtual void eat() override
{
cout << "eats catfood" << endl;
}
void sleep()
{
Animal::sleep();
}
};
int main(int argc, char** argv) {
DogCat *DC = new DogCat();
DC->Cat::sleep();
}
Use virtual inheritance like says #Asesh answer. The problem is the common method eat(). You have to override it.

You should use virtual inheritance
class Animal
{
public:
Animal(){}
virtual void sleep()
{
cout << "zzzzzzzzz" << endl;
}
virtual void eat() = 0;
};
class Dog: virtual public Animal
{
protected:
Dog(){}
virtual void eat() override
{
cout << "eats dogfood" << endl;
}
};
class Cat : virtual public Animal
{
public:
Cat(){}
virtual void eat() override
{
cout << "eats catfood" << endl;
}
};
class DogCat : public Dog, public Cat
{
public:
DogCat(){}
using Dog::eat;
};
int main(int argc, char** argv) {
DogCat *DC = new DogCat();
DC->sleep();//Error
}

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;
}

Strategy pattern on C++

I'm trying port example of Strategy pattern from HeadFirst book from java to C++
#include "iostream" using namespace std;
class IFlyBehavior
{
public:
virtual void fly() = 0;
};
class FlyWithWings : public IFlyBehavior
{
public:
void fly() override
{
cout << "fly!";
}
};
class FlyNoWay : public IFlyBehavior
{
public:
void fly() override
{
cout << "no fly!";
}
};
class IQuackBehavior
{
public:
virtual void quack() = 0;
};
class Quack : public IQuackBehavior
{
public:
void quack() override
{
cout << "Quack!";
}
};
class Squeak : public IQuackBehavior
{
public:
void quack() override
{
cout << "Squeak!";
}
};
class MuteQuack : public IQuackBehavior
{
public:
void quack() override
{
cout << "Can't quack";
}
};
class Duck : public IFlyBehavior, IQuackBehavior
{
public:
FlyWithWings* fly_behavior;
Quack* quack_behavior;
void swim()
{
cout << "Swim!";
}
virtual void display() = 0;
void performQuack()
{
quack_behavior->quack();
}
void performFly()
{
fly_behavior->fly();
}
};
class MallardDuck : public Duck
{
public:
MallardDuck()
{
quack_behavior = new Quack();
fly_behavior = new FlyWithWings();
}
void display() override
{
cout << "Mallard!";
}
};
class RedheadDuck : public Duck
{
public:
void display() override
{
cout << "RedHead!";
}
};
class DecoyDuck : public Duck
{
public:
void display() override
{
cout << "DecoyDuck!";
}
};
class RubberDuck : Duck
{
public:
void display() override
{
cout << "RubberDuck!";
}
};
int main(int argc, char* argv[])
{
Duck* md = new MallardDuck;
md->performFly();
md->performFly();
return 0;
}
But i got error:
E0322 object of abstract class type "MallardDuck" is not allowed: Duck d:\Code\CODE\C++\Duck\Duck\Source.cpp 119
It's seems like compiler not see realized classes, why this happen? Any ideas about it? How I must do?
You cannot instantiate a MallardDuck, because a MallardDuck is a Duck which supposedly implements the IQuackBehavior interface but has failed to override void Quack(). Same for the flying behaviour.
I recommend that you do not try to "translate" Java to C++; they are completely different languages and should be treated as such. Here are some good books for learning the language you're actually using.
MallardDuck inherits Duck which inherits from the abstract classes IFlyBehavior and IQuackBehavior. But nowhere do you override the abstract functions from those abstract classes.
Instead you seem to have a weird mix inheritance with encapsulation.

How to run abstract class functions and the inherited functions?

I have just learnt about abstract class but I don't understand much. Is it possible to run abstract class functions and the inherited functions all at once?..
For example,
class Animals
{
public:
virtual void Display() = 0;
};
class Dog : public Animals
{
void Display()
{
cout << "This is Dog!" << endl;
};
class Cat : public Animals
{
void Display()
{
cout << "This is Cat!" << endl;
}
};
and I have another class called Zoo which will run the abstract function in class Animals
class Zoo : public Animals
{
Animals* animal;
animal->Display();
}
and the output I want is
This is Dog!
This is Cat!
When I run this, it has errors.. Is there any other ways to get this output? Thanks :)
First off, there's a syntax error:
class Animals
{
public:
virtual void Display() = 0;
};
class Dog : public Animals
{
void Display()
{
cout << "This is Dog!" << endl;
}
};
class Cat : public Animals
{
void Display()
{
cout << "This is Cat!" << endl;
}
};
Then if you want to create Dog and Cat instances you call new operators for these classes:
class Zoo : public Animals
{
void Display()
{
Animals* animal1;
animal1 = new Cat();
animal1->Display();
delete animal1;
Animals* animal2;
animal2 = new Dog();
animal2->Display();
delete animal2;
}
}
This should get your desired output.
animal->Display(); results in undefined behaviour because animal is not initialized, so first initialized it as
Cat my_cat;
Animals* animal = &my_cat;
animal->Display();
OR
Animals* animal = new Cat();
animal->Display();
....
delete animal;
Here is your Code, explanation is there in comments.
class Animals {
public:
virtual void Display() = 0;/*its a PVF , in every derived class it should be re-defined */
};
class Dog : public Animals {
void Display() {
cout << "This is Dog!" << endl;
};
};
class Cat : public Animals {
void Display() {
cout << "This is Cat!" << endl;
}
};
class Zoo : public Animals {
public :
void Display() {
#if 1
Dog my_dog;
Animals *animal = &my_dog; /** Display() of Animal class will be invoked bcz Display() is declared as virtual */
animal->Display();
#endif
#if 0
Animals* animal = new Cat(); /** Display() of Cat class eill be invoked */
animal->Display();
delete animal;
#endif
}
};
int main() {
Zoo my_zoo;
my_zoo.Display();
return 0;
}
I hope it helps you.
Is there a way to only call the base class and run the inherited classes too?
I think you want this:
#include <iostream>
#include <memory>
class Animals
{
public:
virtual void Display() = 0;
virtual ~Animals() = default;
};
class Dog : public Animals
{
void Display() override
{
std::cout << "This is Dog!" << std::endl;
}
};
class Cat : public Animals
{
void Display() override
{
std::cout << "This is Cat!" << std::endl;
}
};
class Goat : public Animals
{
void Display() override
{
std::cout << "This is Goat!" << std::endl;
}
};
int main()
{
Animals* animal = new Dog;
animal->Display();
delete animal; // delete at some point to avoid memory leak as Dog is allocated on the heap
Cat cat;
animal = &cat;
animal->Display(); // no delete needed, as Cat is allocated on the stack and will cleared when goes out of scope
std::unique_ptr<Animals> animal2 = std::make_unique<Goat>();
animal2->Display(); // no delete needed, Goat is allocated on the heap but will be cleared when goes out of scope
return 0;
}
https://ideone.com/yoVt4G
Threw std::unique_ptr in the mix for variety

C++ - Function of a class with different statements

i'm trying to make specifics statements on the same class function's.
there's an example of what i'm triying to make
#include <stdio.h>
class animal
{
public:
void Talk();
};
int main()
{
animal dog;
animal cat;
dog::Talk()
{
printf("Wof");
};
cat::Talk()
{
printf("Meow");
};
dog.Talk();
cat.Talk();
return 0;
}
I also try it with class inheritance, something like
#include <stdio.h>
class cat
{
public:
void Talk()
{
printf("Meow");
};
};
class dog
{
public:
void Talk()
{
printf("Wof");
}
};
class animal{};
int main()
{
animal Schnauzer: public dog;
animal Siamese: public cat;
Schnauzer.Talk();
Siamese.Talk();
return 0;
}
There's a way to do something like this?
It is a very basic thing to do in c++. You just have to know a little bit about inheritance. However, I am guessing that you are new to c++ and don't have much experience in using inheritance. So, I am giving you a simple solution using class inheritance below. Feel free to ask me if there is any confusion.
#include <iostream>
using namespace std;
class animal {
public:
virtual void Talk() {cout << "default animal talk" << endl;}
};
class dog: public animal {
public:
void Talk() {cout << "Wof" << endl;}
};
class cat: public animal {
public:
void Talk() {cout << "Meow" << endl;}
};
int main()
{
dog Schnauzer;
cat Siamese;
Schnauzer.Talk();
Siamese.Talk();
return 0;
}

Can I Perform inheritance outside of the class in C++11?

Say I want to overload a function outside of my classes with different pointer types. Can I do this in C++11?
struct Bird;
struct Bear;
struct Animal {
virtual Bird* AsBird() = 0;
virtual Bear* AsBear() = 0;
};
struct Bird : public Animal{
virtual Bird* AsBird(){ return this; }
virtual Bear* AsBear(){ return NULL; }
};
struct Bear : public Animal{
virtual Bird* AsBird(){ return NULL; }
virtual Bear* AsBear(){ return this; }
};
void Print(Animal* a){
cout << "I don't know what animal this is!" << endl;
}
void Print(Bear* b){
cout << "That's a bear!" << endl;
}
void Print(Bird* b){
cout << "That's a bird!" << endl;
}
int main(int argc, char* argv[]){
Animal* a = new Bear;
Bear* bear;
Bird* bird;
if (bear = a->AsBear()){
Print(bear);
} else if (bird = a->AsBird()){
Print(bird);
}
return 0;
}
This code works, but it's absolutely awful. I have tried playing around with templates and auto, but the compiler doesn't want anything to do with my evil experiments. Is there a legitimate way of doing this?
What you did is overloading the Print free function by changing the type of its parameter, there is no inheritance involved, and this is perfectly legal.
But you don't need it (or any dynamic_cast-like as you did) : What you should do is add a virtual void Print() const = 0 in your Animal base class instead, and override it in each derived class.
Example:
struct Animal {
virtual void Print() const = 0;
};
struct Bird : public Animal{
void Print() const { cout << "That's a bird!\n"; }
};
struct Bear : public Animal{
void Print() const { cout << "That's a bear!\n"; }
};
int main(){
Animal* a = new Bear;
a->Print();
Animal* b = new Bird;
b->Print();
}
As quantdev noted, the traditional way is adding a virtual function to your class hierarchy.
However, if you don't want to do it, you can use dynamic_cast, which was invented specifically for purposes like this.
struct Animal {
virtual ~Animal() {} // base class must have a virtual method to use dynamic_cast
};
...
if (bear = dynamic_cast<Bear*>(a)){
Print(bear);
} else if (bird = dynamic_cast<Bird*>(a)){
Print(bird);
}
This is a little better than what you have: if you add another inheriting class, you don't have to change your base class; you must only change your main function and add a new printing function.
If this is still "awful", maybe you should make Print a virtual function.
This looks like a use case for the visitor pattern.
struct Bird;
struct Bear;
struct Visitor
{
virtual void Visit(Bird& x) = 0;
virtual void Visit(Bear& x) = 0;
};
struct PrintVisitor : Visitor
{
void Visit(Bird& x) override { cout << "That's a bird!" << endl; };
void Visit(Bear& x) override { cout << "That's a bear!" << endl; };
};
struct Animal
{
virtual void Accept(Visitor& v) = 0;
};
struct Bird : public Animal
{
void Accept(Visitor& v) override { v.Visit(*this); }
};
struct Bear : public Animal
{
void Accept(Visitor& v) override { v.Visit(*this); }
};
int main(int argc, char* argv[])
{
Bear bear;
Bird bird;
PrintVisitor visitor;
Animal* a = &bear;
a->Accept(visitor);
a = &bird;
a->Accept(visitor);
}
Of course, it might just be easier to make Print a virtual member function.
The AsBear, AsBird functions, you've simply reimplemented dynamic_cast.
As far as the overloads of Print goes, the simplest solution here is to make Print be a virtual function in the Animal hierarchy.
My recommended solution would be to use the visitor pattern. Since that's what it seems like you're trying to do by decoupling the Print function and the class hierarchy.
#include <iostream>
struct Bird;
struct Bear;
struct Animal {
struct Visitor {
virtual void operator()(const Bird *) const = 0;
virtual void operator()(const Bear *) const = 0;
};
virtual void Accept(const Visitor &visitor) const = 0;
};
struct Bird : public Animal {
virtual void Accept(const Visitor &visitor) const override {
visitor(this);
}
};
struct Bear : public Animal {
virtual void Accept(const Visitor &visitor) const override {
visitor(this);
}
};
struct Print : public Animal::Visitor {
virtual void operator()(const Bird *) const override {
std::cout << "Bird" << std::endl;
}
virtual void operator()(const Bear *) const override {
std::cout << "Bear" << std::endl;
}
};
int main() {
Bird bird;
Animal *animal = &bird;
animal->Accept(Print());
}