0

I got a template class that will store objects of derived classes from a base class, as an example: Template class vector, base class b, derived class d.

class Animal {
protected:
    std::string m_name;

public:
    Animal() {}
    Animal (std::string name): m_name {name} {}
    virtual void set_name(std::string name) {m_name = name;}
    virtual std::string get_name () {return m_name;}
    virtual std::string regn()  const { return "???"; }

    virtual ~Animal(){
    cout << "Destructor animal"<<'\n';}
};
class Bird: public Animal {
public:

    Pasare() : Animal(){}
    Pasare(std::string name)
        : Animal{ name }{}
    void set_name (std::string nume){
    m_name = nume;}

    std::string get_name(){
    return m_name;}

    std::string regn()  const override {return "BIRD";}
     ~Pasare (){
    cout << "destructor pasare"<<'\n';}
 };
template <class T>
class Atlas
{
private:

    int m_length{};
    T* m_data{};

public:
    void SetLungime(int j);
    Atlas(int length)
    {
        assert(length > 0);
        m_data = new T[length]{};
        m_length = length;
    }

    Atlas(const Atlas&) ;//= delete;
    Atlas& operator=(const Atlas&);// = delete;

    ~Atlas()
    {
        delete[] m_data;
    }

    void erase()
    {
        delete[] m_data;

        m_data = nullptr;
        m_length = 0;
    }

    T& operator[](int index)
    {
        assert(index >= 0 && index < m_length);
        return m_data[index];
    }
    int getLength() const;
};
template <class T>
int Atlas<T>::getLength() const 
{
  return m_length;
}
template <class T>
void Atlas<T>::SetLungime(int j){m_length = j;
m_data = new T[j];
}

int main () {

Atlas<Animal> AtlasAnimal(1);
Bird b{"Eagle"};
Animal &a{b};
AtlasAnimal[0] = a;
cout << AtlasAnimal[0].get_name << " " << AtlasAnimal[0].regn();  -- This prints "Eagle", 
which is good and "???" instead of "BIRD" as i wanted.

I don't know how to handle this, cause overriding the function regn works well; cout<<a.regn() prints "BIRD" , as wanted. I tried to do a dynamic_cast as shown:

cout << AtlasAnimal[0].get_name << " " << (dynamic_cast<Bird&>AtlasAnimal[0]).regn(); but it fails, saying terminate after throwing instance of : std::bad_cast

  • `get_name` should be `get_name()` in your `cout` statement – Cory Kramer May 17 '21 at 12:33
  • Your `Atlas` stores `Animal` objects, that's it. No matter what you put into it, it will be an `Animal`. Playing games with `dynamic_cast` will not change anything. Every subclass will be sliced away, as explained in the linked question. This has nothing to do with `dynamic_cast` or templates. See the linked question for more information and alternative approaches. – Sam Varshavchik May 17 '21 at 12:35

0 Answers0