Jump to content

    

Есть ли возможность в наследованном классе изменить содержимое массива родительского класса

Добрый день, коллеги! Наслышан о чудесах Си++17, которым я теперь располагаю в новом IAR'е. И мне вот интересно, можно ли поменять содержимое (ну или дополнить) массива, объявленного в родительском классе при наследовании?

Ну например

class AppBase {
  public:
  protected:
  DrvBase * m_array[]; // здесь храним указатели на драйвера, используемые в приложении, но пока он пуст, т.к. это базовый класс, пригодный для всех применений
};

class MyCoolerApplication : public AppBase {
  public:
  AppBase() {
    m_array.add(UartDrv);    // для управления вентилятором нам нужен драйвер последовательного порта
    m_array.add(FanDrv);     // а ещё драйвер самого вентилятора
    m_array.add(KeyboardDrv);// ну и драйвер клавиатуры
    
    openAllDrivers(); // открываем (инициализируем) все драйвера
  }
  
  private:
  rettype_t openAllDrivers() {
    for( auto &it : m_array ) {
      auto result it->open();
      if( result != rettype_t::ok )
        return result;
    }
    return rettype_t::ok;
  }
};

Естественно, это псеводокод. Но принцип должен быть понятен.

Теперь есть условия:

1. Никакой динамической памяти. Иначе бы использовал std::vector.

2. Обязательно массив m_array с указателями на драйвера должен быть во Flash, т.к. его содержимое известно на этапе сборки проекта.

3. Я смотрел это, где-то чувствую, что почти оно, но знаний не хватает полностью осознать этот пример.

 

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

Share this post


Link to post
Share on other sites
3 часа назад, haker_fox сказал:

2. Обязательно массив m_array с указателями на драйвера должен быть во Flash, т.к. его содержимое известно на этапе сборки проекта.

Если он "должен быть во Flash", то почему он у Вас без const?

При public-порождении все члены родительского класса являются частью всех дочерних. Так что сам массив - думаю нельзя.

Но можно создать виртуальную функцию, которая будет возвращать адрес этого массива. И перегружать её для дочерних классов. Или не виртуальную, а обычную - если нет необходимости работы с экземплярами класса через указатели на базовый класс.

 

PS: Всё это есть и в старом IAR-е.

Share this post


Link to post
Share on other sites
20 minutes ago, jcxz said:

Но можно создать виртуальную функцию, которая будет возвращать адрес этого массива.

Гм, идея! В наследуемом классе можно заводить новый массив, заполнять его. А с пустым в родительском классе можно смириться.

21 minutes ago, jcxz said:

Если он "должен быть во Flash", то почему он у Вас без const?

Не придирайтесь)) Я этот код прямо в форме форума забил, мог и накосячить с такими мелочами))

22 minutes ago, jcxz said:

Всё это есть и в старом IAR-е.

Эт понятно. Просто видя "чудеса" Си+=17 я подумал, а вдруг?

Share this post


Link to post
Share on other sites
8 минут назад, haker_fox сказал:

Гм, идея! В наследуемом классе можно заводить новый массив, заполнять его. А с пустым в родительском классе можно смириться.

А можно ещё проще: объявите m_array как static-член и расположите его во флешь. Вам же не надо чтобы у Вас в программе была куча экземпляров одного и того же const-массива?

А в дочерних классах объявляйте указатель на этот массив. Или на свой (если его нужно заменить).

Share this post


Link to post
Share on other sites
2 hours ago, haker_fox said:

Да, можно использовать связные списки, но возможно есть что-то более красивое?

Простой односвязный список. Можно самодельный (даже лучше),  в этом случае все классы драйверов - наследники некого базового класса или класса простого односвязного списка, содержащего поле указателя на следующий элемент. Тут кому как больше нравится.

Сам так делаю, когда добавляю модули проекта в Application. Инициализация, отложенное связывание друг с другом (принцип signal/slot) и запуск модулей выполняется по этому списку, в порядке объявления их экземпляров в классе Application (в разделе private).

А массив, имхо, тут - как собаке пятая нога ))

Share this post


Link to post
Share on other sites
7 minutes ago, Forger said:

Простой односвязный список. Можно самодельный (даже лучше),  в этом случае все классы драйверов - наследники некого базового класса или класса простого односвязного списка, содержащего поле указателя на следующий элемент. Тут кому как больше нравится

Но списки - крайне неудачный тип данных для создания во время компиляции.

А кто-нибудь может мне объяснить, зачем сложности с указателем на массив? Наследующий класс - это унаследованные члены наследуемого класса плюс собственные. При этом доступ к членам при публичном наследовании имеется к public и protected членам.
То есть, конструктор для базового класса создаёт массив из базового класса наряду с другими членами базового класса, а конструктор наследующего - создаёт члены наследущего, он не создаёт новый массив, унаследованный из базового. Это один и тот же массив.

Share this post


Link to post
Share on other sites
6 минут назад, one_eight_seven сказал:

А кто-нибудь может мне объяснить, зачем сложности с указателем на массив?

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

Share this post


Link to post
Share on other sites
7 minutes ago, one_eight_seven said:

Но списки - крайне неудачный тип данных для создания во время компиляции.

Список - это не тип данных, это объект. И при чем тут время компиляции? 

 

Share this post


Link to post
Share on other sites
Just now, jcxz said:

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

Так сделайте его public. или просто любовь к тривиальным методам?

Quote

Список - это не тип данных, это объект. И при чем тут время компиляции? 

Первый пост:

Quote

2. Обязательно массив m_array с указателями на драйвера должен быть во Flash, т.к. его содержимое известно на этапе сборки проекта.

 

Share this post


Link to post
Share on other sites
Только что, one_eight_seven сказал:

Так сделайте его public. или просто любовь к тривиальным методам?

Кого сделать public?  :wacko2:

Share this post


Link to post
Share on other sites
1 minute ago, Forger said:

Список - это не тип данных

ага. и int - тоже. Господи... Go get some education.

Just now, jcxz said:

Кого сделать public?  :wacko2:

массив в базовом классе.

Share this post


Link to post
Share on other sites
Только что, one_eight_seven сказал:

массив в базовом классе.

И что это даст? ТС перегружать его хочет в дочерних классах.

Share this post


Link to post
Share on other sites
2 minutes ago, jcxz said:

И что это даст? ТС перегружать его хочет в дочерних классах.

Его нельзя перегружать. Перегружаются методы. Данные можно изменять, инициализировать и т.п. И это можно сделать в наследующем классе.

P.S. а даст это доступ  к массиву извне объектов (Внутри объектов этот доступ и так уже есть безо всяких дополнительных указателей)

Edited by one_eight_seven

Share this post


Link to post
Share on other sites
Только что, one_eight_seven сказал:

Его нельзя перегружать. Перегружаются методы.

Я вообще-то это знаю. О чём и написал в первом посте. "Перегружать" в этом контексте следовало читать как - "заменить в дочерних на свой экземпляр массива".

Только что, one_eight_seven сказал:

Данные можно изменять, инициализировать и т.п. И это можно сделать в наследующем классе.

Так покажите как? Кроме тех методов что уже предложены.

Share this post


Link to post
Share on other sites
15 minutes ago, one_eight_seven said:

ага. и int - тоже. Господи...

int - это тип, экземпляр данных с типом int - объект.

Список каких-то типов данных - это тоже тип данных. Экземпляр списка - объект.

Время компиляции имеет отношение к созданию объектов, а разбором типов данных занимается препроцессор компилятора.

Quote

Go get some education.

Вот именно! 

 

 

12 minutes ago, one_eight_seven said:

а даст это доступ  к массиву извне объектов

После этого можно смело переходить на старый добрый C :dirol:

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now