0

I have kind of a diamond kind of inheritance. But that is not the problem. I am passing a casted type through a setter method. However when I try to recast it to its original type I get bad_cast. Code snippet of the problem below. What am I doing wrongly and how can I fix it.

#include <iostream>

class Animal {
public:
    virtual ~Animal() {}

    void SetName(const std::string name) {
        name_ = name;
    }

    std::string const &Name() {
        return name_;
    }

private:
    std::string name_;
};


class AnimalA : virtual public Animal {
public:

};

class AnimalB : virtual public Animal {
public:

};

class AnimalAB : public AnimalA, AnimalB {
public:

};

Animal h;

void GetAnimal(const Animal &animal) {
    h = animal;
}

int main() {
    Animal *animal = new AnimalA();
    GetAnimal(*animal);
     AnimalA f = dynamic_cast<AnimalA&>(h);
    return 0;
}
r360
  • 49
  • 4

1 Answers1

1

C++ is not Java nor Python. In those language, a variable is only a reference to an object, so it could also contain a instance of a subclass. C++ has objects, pointers and 2 kinds of references (lvalue and rvalue). Both pointers and references can be used for instances of subclasses, but objects cannot because of the slicing problem.

Here the design problem is that you have a global Animal object that you want to be able to receive an instance of AnimalA subclass. This is simply not possible in C++.

If you have no ownership constraints, you could use a raw pointer for h, because it would be natively polymorphic:

const Animal *h;

void GetAnimal(const Animal &animal) {
    h = &animal;
}

int main() {
    Animal *animal = new AnimalA();
    GetAnimal(*animal);
    const AnimalA *pf = dynamic_cast<const AnimalA*>(h);
    AnimalA f;
    if (pf != NULL) {
         f = *pf;       // successful copy assignment from the initial AnimalA object
    }
    del animal;         // never forget to destroy what has been allocated
    return 0;
}

It you do not want to be bothered by the new, del question, you could use an automatic object instead of a dynamic one:

    ...
    AnimalA animal;
    GetAnimal(animal);
    ...
Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252