Polymorphism (or inheritance) can lead to problems if your hierarchy becomes too big.
For example, it might be logical to have the following classes:
class Animal;
class Mammal : public Animal;
class Dog : public Mammal;
class Cat : public Mammal;
class Fish : public Animal;
But if at a certain point you need to make a distinction between animals that can swim (dog, fish) and animals that can't swim (imagine for a moment that a cat can't swim). Then it would be more logical to have it like this:
class Animal;
class SwimmingAnimal: public Animal;
class Dog : public SwimmingAnimal;
class Fish: public SwimmingAnimal;
class NonSwimmingAnimal: public Animal;
class Cat : public NonSwimmingAnimal;
You could try to implement both hierarchies using virtual inheritance but this quickly leads to lots of problems (one of it is also called the "diamond problem").
Using interfaces can solve many of these problems, but at a cost.
class Animal;
class Dog : public Animal, public IMammal, public SwimmingAnimal;
class Cat : public Animal, public IMammal;
class Fish: public Animal, public SwimmingAnimal;
Since the classes only inherit from interfaces, they cannot easily share the same functionality. Therefore sharing functionality must be implemented via containment. If Dog and Fish want to offer both the 'swim' functionality, they have to provide the swim method, and implement it by forwarding its call to a separate Swim class, something like this (this is all pseudo-code):
class Dog : public Animal, public IMammal, public SwimmingAnimal
{
public:
void swim(double speed) {m_swim->swim(speed);}
private:
Swim m_swim;
}