dynamic — создание массива в c ++ типа superclass для динамического хранения объектов подкласса

Пожалуйста, рассмотрите следующий код:

    #include <iostream>
using namespace std;
class superclass;
class subclass;
class subclass2;
class superclass
{
public:
unsigned int a;
superclass **superman;

};
class subclass : public superclass
{
public:
unsigned int b;
};
class subclass2 : public superclass
{
public:
unsigned int b;
};
class runner
{
public:
superclass **superman;
runner()
{
*superman=new superclass[2];
superman[0]=new subclass;
superman[0]->a=3;
superman[1]=new subclass2;
superman[1]->a=4;
}

};
int main() {

runner r;
cout<<r.superman[0]->a<<" "<<r.superman[1]->a;
return 0;
}

Как вы можете видеть, я хочу создать динамически размещенное хранилище ссылок на родительский класс, каждый из которых может затем указывать на дочерний класс, как только я не знаю, как извлечь дочерний класс снова из этого массива, чтобы я мог получить доступ к его переменная b;

Я попробовал следующие подходы, но они не сработали для меня и выдают ошибку
«преобразование из суперкласса * в нескалярный тип» подкласс «запрошено» и
«требуется преобразование из ‘суперкласса * в нескалярный тип’ subclass2 ‘»

    subclass s1=r.superman[0];
subclass2 s2=r.superman[1];

Я уверен, что мне не хватает чего-то маленького.

PS: я не мог найти похожий вопрос, но если он существует, пожалуйста, перенаправьте меня,
Также я хотел бы решение, которое не требует от меня использовать вектор или любой встроенный
уже существующий класс библиотеки.

3

Решение

Вы действительно хотите умный указатель в этом случае, и суперкласс не должен иметь указатель на себя. Вы можете хранить указатель суперкласса в векторе, который указывает на реальный производный класс, так что полиморфизм все еще работает:

#include <memory>
#include <vector>

struct superclass
{
public:
superclass() : a(0) {}
virtual ~superclass() {}  // it's important to define virtual destructor as superclass is a base class
int getA() const { return a; }

private:
unsigned int a;
};

class subclass : public superclass
{
public:
unsigned int b;
};
class subclass2 : public superclass
{
public:
unsigned int b;
};

class runner
{
public:
std::vector<std::unique_ptr<superclass>> superman;
runner()
{
superman.emplace_back(new subclass());
superman.emplace_back(new subclass2());
}
};

Тогда вы можете получить к нему доступ просто:

   int main()
{
runner r;
std::cout << r.superman[0]->getA() <<" " < <r.superman[1]->getA();
return 0;
}

Примечание: скрывайте свои данные, если можете, обращайтесь к данным через функции set / get, не объявляйте участников открытыми.

2

Другие решения

    superclass **superman;
runner()
{
*superman=...

Эти несколько строк кода дают неопределенное поведение коду. Вы не можете разыменовать неинициализированный указатель и ожидать, что все будет работать нормально.

1

Добавить virtual деструктор в superclass и использовать dynamic_cast:

class superclass
{
public:
unsigned int a;
superclass **superman;
virtual ~superclass(){}; // You must at least have one virtual method
// in your superclass and destructor is good choice
// Otherwise, dynamic_cast wouldn't work:
// error: ... (source type is not polymorphic) !
};
// ...
// s1 and s2 must be pointers:
subclass  *s1=dynamic_cast<subclass* >(r.superman[0]);
subclass2 *s2=dynamic_cast<subclass2*>(r.superman[1]);
//...

Примечание. Будьте внимательны при приведении из базового класса к производному классу. И не забудьте освободить выделенную память.

1
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector