Jump to content

    
Sign in to follow this  
haker_fox

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

Recommended Posts

Добрый день, коллеги! Наслышан о чудесах Си++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
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
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

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this