How to fix this ambiguity for diamond problem - c++

I am exploring diamond problem. I have written below code. However it shows ambiguous issue. How to resolve it?
Is it possible without overriding method in Snake class?
#include <iostream>
class LivingThing {
protected:
void breathe()
{
std::cout << "I'm breathing as a living thing." << std::endl;
}
};
class Animal : virtual protected LivingThing {
protected:
void breathe() {
std::cout << "I'm breathing as a Animal." << std::endl;
}
};
class Reptile : virtual public LivingThing {
public:
void breathe() {
std::cout << "I'm breathing as a Reptile." << std::endl;
}
};
class Snake : public Animal, public Reptile {
};
int main() {
Snake snake;
snake.breathe();
getchar();
return 0;
}

What happens here is that Animal and Reptile both overwrite the LivingThing::breathe() method with their own version. Snake, thus, inherits two different methods, both called breathe, one from each of its base classes. When you then write
snake.breathe();
the name breathe is ambiguous because it could refer to either Animal::breathe or Reptile::breathe. You have to explicitly tell which one should be called, for example
snake.Reptile::breathe();
This is most likely not what you wanted. breathe() is not a virtual method. You most likely wanted it to be a virtual method, however, in which case you most definitely should have a look at How does virtual inheritance solve the "diamond" (multiple inheritance) ambiguity?.

Related

Calling multiple virtual functions in a derived class

I am in the process of creating a scene graph for a 2D game engine. I've created a base class called Node, which is derived by Sprite, which in turn is derived by Player. Each class has the virtual function update(). I want to call every update() in each class. I don't know if this is possible (Except using base::update(), but that's a little messy with many derived classes).
The following code provides a little insight into the current structure of my project.
#include <iostream>
class Base
{
public:
virtual void print()
{
std::cout << "Hello from Base ";
}
};
class Derived : public Base
{
public:
virtual void print()
{
std::cout << "and Derived!" << std::endl;
}
};
int main()
{
Derived foo = Derived();
foo.print(); // Obviously outputs only "and Derived!"
}
While the above does exactly as expected, my desired output is actually "Hello from Base and Derived!".
I know I can put Base::print() at the top of Derived::print(), but I am looking for a method to that's a little cleaner with many derived classes on top of each other.
I'm a little new to C++ as a language, and I couldn't find info on this subject. I'm open to complete changing my approach if it's not in the style of proper polymorphism. I'd rather do things right than botching it to just get this affect.
I know I can put Base::print() at the top of Derived::print(), but I am looking for a method to that's a little cleaner with many derived classes on top of each other.
You have to do that explicitely if you want it, That's the whole point of overriding with polymorphism.
class Derived : public Base
{
public:
virtual void print()
{
Base::print();
std::cout << "and Derived!" << std::endl;
}
};
As you're mentioning graphs (tree like structures), you should have a look at the Visitor Pattern.
Sometimes C++ does something you are not expecting.
My advice is to use a feature of the C language that it has to support.
In this case, I used union to achieve the programmatic effect you are seeking:
#include <iostream>
class Base
{
public:
virtual void print()
{
std::cout << "Hello from Base ";
}
};
class Derived : public Base
{
public:
virtual void print()
{
std::cout << "and Derived!" << std::endl;
}
};
int main(void);
int main()
{
Base foo;
Derived bar;
union foobar {Base *b; Derived *d;} fb;
fb.b = &foo; fb.b->print();
fb.d = &bar; fb.d->print();
return 0;
}
CODE LINK: http://ideone.com/JdU8T6

C++ wrapper class that is derived from an abstract base class and calls a method in another class that is also derived from the abstract base class

I have an abstract class called Animal and a derived class called cow.
Cow provides definitions of the pure virtual functions in Animal.
I want to create a class called AnimalWrapper that inherites from Animal. I want the method AnimalWrapper.speak() to simply call cow.speak().
Do I just need a reference to a cow object in the animalwrapper class so that I can call the non static method speak?
How would I do this?
#include<iostream>
#include<cstdlib>
using namespace std;
#include <string>
class Animal // This Animal is an abstract base class
{
public:
Animal(){};
virtual const char* speak() = 0; //pure virtual function
};
class Cow: public Animal
{
public:
Cow(){};
virtual const char* speak() {
cout << "I am a cow" << endl;
return "Moo ";
}
};
class AnimalWrapper: public Animal
{
public:
AnimalWrapper(){}
virtual const char* speak() {
cout << "Calling cow class speak() method" << endl;
//Call Cow::speak()
return "Moo";
}
};
int main()
{
AnimalWrapper AnimalWrapper_obj ;
std::cout << AnimalWrapper_obj.speak() << '\n';
}
Based on your comment here is an example of a class AnimalWrapper taking an external reference of a Cow instance using move semantic. Since it is a move constructor and not a copy constructor you should be careful when using your original object.
If you want to keep your original instance of Cow, then you might need a copy constructor instead (but you will duplicate your Cow instance).
You could also store a pointer or a reference in a class Cow * cowInstanceor Cow& cowInstance) but you risk ending up with a dangling pointers / reference (hence why I used move semantics here).
#include<iostream>
#include<cstdlib>
#include <memory>
// using namespace std; // <= Using namespace std is considered bad practice
#include <string>
class Animal // This Animal is an abstract base class
{
public:
Animal(){}
virtual ~Animal() {} // Do some research about the difference between virtual and non virtual destructor in C++
virtual std::string speak() = 0; //pure virtual function
};
class Cow: public Animal
{
public:
Cow(){}
Cow(const Cow& cow) = delete;
Cow(Cow&& _cow) {std::cout << "Move constructor " << std::endl;}
virtual ~Cow() {}
// virtual const char* speak() { // <= Use std::string in c++
virtual std::string speak() {
++m;
std::cout << "I am a cow : "<< m << std::endl;
return std::string("Mooo");
}
private:
int m = 0;
};
class AnimalWrapper // : public Animal // <= This is unnecessary
{
public:
AnimalWrapper(std::unique_ptr<Cow> _cow) : cowInstance((std::move(_cow))) {
}
std::string speak() {
std::cout << "Calling cow class speak() method" << std::endl;
return cowInstance->speak();
}
private:
std::unique_ptr<Cow> cowInstance;
};
int main()
{
std::unique_ptr<Cow> cow(new Cow);
cow->speak();
std::cout << "Hello, world!" << std::endl;
AnimalWrapper AnimalWrapper_obj(std::move(cow));
std::cout << AnimalWrapper_obj.speak() << '\n';
}
Since the problem you are trying to solve is still unclear to me, this is probably not an ideal / perfect solution. Nonetheless, it is an example of what you asked according to my understanding.
Assuming you want to extend the API in use, but cannot modify it itself, I conclude that you want to provide a parallel hierarchy:
namespace wrapped
{
class Animal
{
public:
virtual ~Animal();
virtual std::string speak();
};
class Cow : public Animal
{
public:
std::string speak() override;
unsigned int giveMilk() { return 77; }
};
}
namespace wrapping
{
class Animal
{
protected:
wrapped::Animal& animal;
Animal(wrapped::Animal& animal)
: animal(animal)
{ }
public:
virtual ~Animal() { }
// does not need to be virtual, we can profit from
// polymorphism of referred object...
//
// still it CAN be virtual, if you want to allow derived
// wrappers as well to modify the inherited speak!
std::string speak()
{
return animal.speak();
}
};
class Cow : public Animal
{
public:
Cow(wrapped::Cow& cow)
: Animal(cow)
{ }
// speak is inherited
unsigned int giveMilk()
{
// don't need dynamic cast as we passed a reference
// to cow object to base class constructor...
return static_cast<wrapped::Cow&>(animal).giveMilk();
}
};
}
A variant you can use if Cow inherits virtually from Animal allows you to write a little less of code:
namespace wrapping
{
class Animal : private virtual wrapped::Animal
{
public:
using wrapped::Animal::speak;
};
class Cow : public Animal, private wrapped::Cow
{
public:
using wrapped::Cow::speak;
};
}
If Cow does not inherit virtually, though, your wrapping Cow would inherit two instances of wrapped::Animal which would lead to a number of problems not being discussed here for now.
If you override speak in wrapping::animal, though, you need to provide a final overrider in wrapping::Cow to resolve the ambiguity between both inherited overridden variants of speak.
Actually, you could inherit from the wrapped bases publicly, then you wouldn't need the using declarations any more (final overrider issue remains, though), but that would allow for a wild mixture between wrapped and wrapping classes, which you'd most likely want to prevent.

how to combine two classes that share the same base class in C++?

I give the following example to illustrate my question:
class Base
{
public:
virtual void do()=0;
}
class A: public Base
{
public:
void do();
};
class B: public Base
{
public:
void do();
}
class AB: public Base
{
public:
void do()
{
a_.do();
// if not succeed
{
b_.do();
}
}
private:
A a_;
B b_;
}
From the above codes, we can see that class A, B and AB come from the same Base class. class AB, however, needs to invoke both class A and class B. Here is my question: what's the potential problem with the class AB? Are there other alternatives?
One alternative might be:
class Base
{
public:
virtual void do()=0;
}
class A: public Base
{
public:
void do();
};
class B: public Base
{
public:
void do();
}
class AB: public A
{
public:
void do()
{
A::do();
// if not succeed
{
b_.do();
}
}
private:
B b_;
}
I have no idea what you really want to achieve. But if all of your classes should only have one copy of instance data from Base, you need a virtual Base class.
The problem from your first example with AB is, that you have three! times data of class Base. One from inherit Base, one as part of Member B which itself derives from Base and the same from Member A. Is that what you intend?
I give you the following snipped to see how you can work with exact ONE copy of Base in all of your class instances. Maybe that is what you want to get?
I add some data to Base to see how construction works while using virtual base classes. It is important that the base class constructor will not be called from the constructors of directly inherited classes! You need to call the constructor directly from the outermost constructor as shown in class AB constructor!
As a remark: Virtual Base classes should be used only if nothing else fits the design. Often the need of such a solutions shows a design problem. But as always in programming: If this fits exactly your needs, it is technically absolutely ok to do it.
class Base
{
private:
std::string text;
public:
Base( const std::string& str ): text(str) {}
virtual void Do() { std::cout << text << std::endl; }
};
class A: virtual public Base
{
public:
A():Base("Default from A") {}
void FuncA() { std::cout << "FuncA" << std::endl; }
void Do() { std::cout << "Via A" << std::endl; Base::Do();}
};
class B: virtual public Base
{
public:
B(): Base ("Default from B") {}
void FuncB() { std::cout << "FuncB" << std::endl; }
};
class AB: public A,B
{
public:
//Important to know that init of Base MUST be done from here and not from A nor B !!
AB( const std::string &s): Base(s) {}
void Do() { std::cout << "Via AB" << std::endl; Base::Do(); A::Do(); B::Do();}
};
int main()
{
A a;
a.Do();
std::cout << "####" << std::endl;
B b;
b.Do();
std::cout << "####" << std::endl;
AB ab("Hallo");
ab.Do();
std::cout << "####" << std::endl;
}
what's the potential problem with the class AB?
I don't know of any well known problem that would necessarily arise from your design. You should ask yourself "Why would there be a problem?".
Are there other alternatives?
There are many alternatives. For example, neither A nor B contain any state, so you could just as well stop using classes in favor of free functions and replace dynamic binding with a function pointer.
To be able to compare different alternatives, you should first decide what problem you are trying to solve.
You should inherit from A and B and not from Base, because A and B already do so.

Access overloaded base class method with same name as derived method

I'm attempting to call a method from a base class with the same name as a method in the derived class. Here's a simplified example:
#include <iostream>
using namespace std;
class Base
{
public:
void print() {
cout << "Printing from base" << endl;
}
void print(int num) {
cout << "Printing number from base: " << num << endl;
}
};
class Derived : public Base
{
using Base::print;
public:
void print() {
cout << "Printing from derived" << endl;
}
};
int main()
{
Derived x;
x.print();
x.Base::print(1);
//x.print(1); // Gives a compilation error
return 0;
}
Basically, I'd like to be able to call x.print(1) and get "Printing number from base: 1", that is, automatically call the method which matches the signature, even though it resides in the base class.
Without the using Base::print;, I get error: no matching function for call to 'Derived::print(int)', which makes perfect sense due to name hiding.
Thus, I added that line, but now the error is error: 'void Base::print(int)' is inaccessible
Why is this the case? I use public inheritance, so I would have thought it was readily available?
As demonstrated in the example, it works fine to manually call x.Base::print(1);, but I would like to do it more transparently. Then of course I can re-implement a wrapper to the function in the derived class, but that does not seem very elegant either.
I apologize if this has been covered in an earlier question, I read a bunch of them and found a lot of similar cases, but nothing that helped me.
The placement of the using directive decides about the visibility. Simply place it into the public area and you should be fine:
//...
class Derived : public Base
{
public:
using Base::print;
void print() {
cout << "Printing from base" << endl;
}
};
//...
http://ideone.com/06NNk
You can make your functions virtual. Any virtual functions inherited from the base class that aren't overloaded will be called through the derived class.
class base
{
public:
virtual void Foo() {}
}
class Derived
{
}
Derived d;
d.foo(); // calls base::foo()

virtual function issue

I am using native C++ with VSTS 2008. A quick question about virtual function. In my sample below, any differences if I declare Foo as "virtual void Foo()" or "void Foo()" in class Derived? Any impact to any future classes which will derive from class Derived?
class Base
{
public:
Base()
{
}
virtual void Foo()
{
cout << "In base" << endl;
}
};
class Derived : public Base
{
public:
Derived()
{
}
void Foo()
{
cout << "In derived " << endl;
}
};
No difference. But for the sake of readbility I always keep the virtual whenever it is.
No, as long as it has the same signature as the member function in the base class, it will automatically be made virtual. You should make it explicitly virtual, however, to avoid confusing anyone reading the code.