0

So, I have to create a template class that will store objects of another class, like in a vector or a list. I decided to write a simple example, like an atlas for some animals. Until now I got this, but I can not instantiate my vector with animals objects. I get this error:

main.cpp|60|error: could not convert <'brace-enclosed initializer list >()' from 'brace-enclosed initializer list>' to 'Animal'

The animal class is just a base class for the other classes like "bird".

#include <iostream>
#include <assert.h>
#include <list>
using namespace std;
class Animal {
protected:
    std::string m_name;
    Animal (std::string name): m_name {name} {}
public:
    virtual std::string regn() const { return "???"; }
    virtual ~Animal(){
    cout << "Destructor animal"<<'\n';}
};
class Nevertebrate : public Animal{
public:
    virtual std::string regn() const { return "nevertebrate";}
    virtual ~Nevertebrate();
};
class Vertebrate: public Animal {
protected:
  /*  std::string m_name;
    Vertebrate (std::string name)
        :m_name {name} {} */
        Vertebrate (std::string name)
            : Animal {name} {}

public:
    virtual std::string regn() const { return "vertebrate";}
    virtual ~Vertebrate(){
    cout<<"Destructor vertebrate"<<'\n';};
};


class bird: public Vertebrate {
public:
    bird(std::string name)
        : Vertebrate{ name }{}
    void set_name (std::string nume){
    m_name = nume;}

    std::string get_name(){
    return m_name;}
    virtual std::string regn() const {return "pasare";}
    virtual ~bird (){
    cout << "destructor bird"<<'\n';}
 };

template <class T>
class Atlas
{
private:
    int m_length{};
    T* m_data{};

public:

    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 // note class name is Array<T>, not Array
{
  return m_length;
}

int main()
{
   Atlas<Animal> AtlasAnimal(10);

    return 0;
}
1201ProgramAlarm
  • 32,384
  • 7
  • 42
  • 56
  • 2
    `Atlas` will only store animals, not anything derived from `Animal`. The `new T[length]{}` expression will try to default construct `Animal`, which fails because there is no `Animal` default constructor. – 1201ProgramAlarm May 16 '21 at 16:45
  • Possibly `Atlas` should contain a `std::vector>`. If it must be possible to initialize an `Atlas` with a length but no content, then it will need to deal with the possibility of containing some null pointers. – aschepler May 16 '21 at 16:57
  • @1201ProgramAlarm Ah, my bad. I am new to this OOP concept so im still trying to catch it. I thank you a lot man. I was wondering, is there anyway i can set in my template class a static int for the length of the array? I will overload the '+=' operator for this template class and i would like to make my length autoincrement itself with a static integer – Dragos Polifronie May 16 '21 at 17:01
  • Usually `+=` changes just one object, not all objects of the type, so the length shouldn't be `static`. And if you use a `std::vector` rather than raw arrays, the `vector` can always tell you its own length. – aschepler May 16 '21 at 17:04
  • Um that seems like a solution but the thing is that i want to overload the `+=` operator to insert an animal, for example a bird, and when i insert an object i want m_length to increment and be m_length+1. For now i tried to make a function setlength as shown: `void Atlas::SetLength(int j){m_length = j; }` but when i try to initialize AtlasAnimal[j] =Animal p; it gets a memory leak, and i think that is because i make the length bigger but there is an empty object at the end of the array. How should i handle this? Should i try to allocate dinamyc all my classes? – Dragos Polifronie May 16 '21 at 20:31

0 Answers0