Хранение разных объектов дочерних классов от общего родительского | c++

Имеется вот такие 3 класса :

class Item {
public:
    std::string text;
};

class Item1 : Item {
public:
    int number1;
    Item1() {
        this->text = "123";
        this->number1 = 0;
    }
};

class Item2 : Item {
public:
    unsigned int number2;
    Item2() {
        this->text = "321";
        this->number2 = 1000;
    }
};

Проблема заключается в следующем:

std::vector<Item*> map = {};
Item1* i1 = new Item1();
Item2* i2 = new Item2();
map.push_back( i1, i2 );

Не удается хранить таким образом указатели на объекты дочернего класса, я читал решения данной проблемы и по идее должно работать, может я чего-то не понимаю или не так понял?

Если данная проблема решаема, то возникает следующий вопрос, как мне добраться до полей map[0]->number1 и map[1]->number1 если их не существует в типе Item. Очень прошу помочь с данной проблемой

P.S. стандарт с++17


Ответы (2 шт):

Автор решения: Harry

Для начала объявите наследование открытым:

class Item1 : public Item {
class Item2 : public Item {

Затем

map.push_back(i1);
map.push_back(i2);

Но вопрос: что вы хотите дальше? Без виртуальности?

Может, вы хотите что-то вроде этого?

class Item {
public:
    std::string text;
    virtual void out() { cout << text << "\n"; }
};

class Item1 : public Item {
public:
    int number1;
    Item1() {
        this->text = "123";
        this->number1 = 0;
    }
    virtual void out() { cout << text << number1 <<"\n"; }
};

class Item2 : public Item {
public:
    unsigned int number2;
    Item2() {
        this->text = "321";
        this->number2 = 1000;
    }
    virtual void out() { cout << text << number2 <<"\n"; }
};

int main(int argc, char * argv[])
{
    std::vector<Item*> map = {};
    Item1* i1 = new Item1();
    Item2* i2 = new Item2();
    map.push_back(i1);
    map.push_back(i2);

    map[0]->out();
    map[1]->out();

}

Просто без виртуальности вы должны сами помнить, указатель на какой класс лежит в том или ином элементе вектора и не допускать ошибок обращения не к тому классу. А это не то чтобы сложно, но при этом очень легко допустить трудно обнаруживаемую ошибку, а главное — вы теряете самое главное — возможности ООП..

→ Ссылка
Автор решения: CrazyElf

Как вариант, даже и без изменения классов всё работает, если пользоваться приведением типов:

int main() {
    // Write C++ code here
    std::vector<Item*> map = {};
    Item1* i1 = new Item1();
    Item2* i2 = new Item2();
    map.push_back((Item*) i1);
    map.push_back((Item*) i2);
    cout << ((Item1*)map[0])->number1 << "\n";
    cout << ((Item2*)map[1])->number2 << "\n";
    return 0;
}
→ Ссылка