Страниц: [1] 2 3 ... 10
 1 
 : Вчера в 08:23:38 pm 
Автор kim - Последний ответ от da-nie
Цитировать
Вам следует почитать и изучить вопрос, как хранятся данные при виртуальном наследовании. Тут на английском но все же примерно написано, что не так просто оперировать указателями на члены класса участвующих в таком наследовании.

Честно говоря, ни черта не понял, что там написано. Undecided
А так, чисто логически, непонятно, почему я не могу создать указатель на унаследованную функцию и вызвав эту функцию не получить преобразование к унаследованному классу.

Цитировать
И вообще, резюмируя - если вы пришли к виртуальному наследованию, то с вероятностью близкой к единице вы архитектурно неправильно представляете свое решение.

Это возможно. Ведь в конечном итоге я всё заменил агрегацией. Мне изначально нужно было, чтобы все классы работали с одной общей структурой и при этом совсем не хотелось передавать при инициализации ссылку на эту структуру в каждый класс, а также все функции этих классов были бы унаследованы объединяющим классом (делегирование делать плохо - этих функций сильно дофига, и я потому и разделил их на отдельные классы). Поэтому я определил структуру в базовом классе и от него унаследовал все остальные. Так как наследование было виртуальным, то базовый класс и эта структура в объединяющем классе CError находятся в единственном числе и все классы работают с одним и тем же экземпляром.

Цитировать
Все это можно почитать тут

О, спасибо!
Если я правильно понял,что там написано, гарантируется инициализация переменных до объектов.

 2 
 : Вчера в 07:50:37 pm 
Автор kim - Последний ответ от lastcross
Цитировать
Интересная штука получается.
Вот есть у меня базовый класс ...

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

И вообще, резюмируя - если вы пришли к виртуальному наследованию, то с вероятностью близкой к единице вы архитектурно неправильно представляете свое решение.

Цитировать
Кстати, что-то найти не могу порядок инициализации переменных

Все это можно почитать тут

 3 
 : Октября 11, 2018, 07:19:35 pm 
Автор lestat - Последний ответ от da-nie
Кстати, очень спорный сайт www.quizful.net. К примеру, приведена программа и предложено определить результат вычитания двух указателей. Про 32 битную плоскую модель памяти в тексте задачи нет ни слова. Один из вариантов "Это бессмысленно". Вот только верным считается не этот вариант (а размер массива, как результат), хотя давным-давно на том же хабре подробно разобрали, почему нельзя определять размер массива вычитанием указателей.
Ну и куча тестов на простую внимательность (пропустили в комментарии */ звёздочку - попробуй с первого раза заметь Smiley ). Ещё мне встретился массив неопределённой длины в структуре, который вообще-то, помнится, совсем не стандартны и просто фишка ряда компиляторов.

 4 
 : Октября 11, 2018, 07:08:37 pm 
Автор kim - Последний ответ от da-nie
Интересная штука получается.
Вот есть у меня базовый класс ошибок CErrorsBased вида:

Код:
class CErrorsBased
{
 public:  
  //конструктор
  CErrorsBased();
  //деструктор
  virtual ~CErrorsBased() {};
 protected:
  virtual void SetState(void)=0;//задать состояние в памяти
};

От этого класса унаследованы классы ошибок конкретного устройства:

Код:
class CErrorsAcs:virtual public CErrorsBased
{
 public:  
  //конструктор
  CErrorsAcs();
  //деструктор
  ~CErrorsAcs();
 public:
  void Acs_SetCANError(uint32_t index,bool state);//установить ошибку "отказ CAN"
  bool Acs_IsCANError(uint32_t index);//получить, задана ли ошибка "отказ CAN"
};
...
//----------------------------------------------------------------------------------------------------
//установить ошибку "отказ CAN"
//----------------------------------------------------------------------------------------------------
void CErrorsAcs::Acs_SetCANError(uint32_t index,bool state)
{
 cErrorsState.cAcs[index].CANError=state;
 SetState();
}
..

А от этих классов ошибок конкретного устройства унаследован общий объединяющий класс ошибок.

Код:
class CErrors:virtual public CErrorsACU,virtual public CErrorsAcs
{
 public:  
  //конструктор
  CErrors();
  //деструктор
  ~CErrors();
 public:
  void ChangeState(uint32_t index,void (CErrors::*set_function_ptr)(uint32_t,bool),bool (CErrors::*is_function_ptr)(uint32_t));//изменить состояние ошибки на противоположное
 protected:
  void SetState(void);//задать состояние в памяти
};

А вот дальше интересно. Функция ChangeState сделана так:

Код:
//----------------------------------------------------------------------------------------------------
//изменить состояние на противоположное
//----------------------------------------------------------------------------------------------------
void CErrors::ChangeState(uint32_t index,void (CErrors::*set_function_ptr)(uint32_t,bool),bool (CErrors::*is_function_ptr)(uint32_t))
{
 if ((this->*is_function_ptr)(index)==true) (this->*set_function_ptr)(index,false);
                                       else (this->*set_function_ptr)(index,true);                                      
 if ((this->*is_function_ptr)(index)==true) printf("true!\r\n");
 else printf("false!\r\n");
}

То есть, она требует два указателя на функции класса CErrors. Всё просто.
Вызываем: cErrors.ChangeState(index,&CErrors::Acs_SetCANError,&CErrors::Acs_IsCANError);

Компилятор напрягся:
Цитировать
pointer to member cast from virtual base 'CErrorsAcs'
will only work if you are very careful


Не понимаю, зачем он сделал это преобразование (а оно оказалось критичным). Эти методы унаследованы CErrors и в целом ему уже принадлежат.
Запускаем программу. И падаем. А дело в том, что функция класса CErrorsAcs вызывает SetState. Но SetState была определена в CErrorsBased и реализована в CErrors. А компилятор сделал преобразование к классу CErrorsAcs. И была вызвана функция без реализации.

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

Кстати, что-то найти не могу порядок инициализации переменных (и массивов строк вида a[]="sdfdfsdf"; ) и классов и прочих сложных типов между модулями. Вот если в одном модуле класс создаётся глобально и в своём конструкторе вызывает динамическое создание другого класса, который в уже своём конструкторе желает взять строковую константу, то какие гарантии, что эта константа (определённая в том же модуле, где и конструктор её использующий) уже инициализирована? Для типа std::string - никаких, а вот для вида a[]="sdfdfsdf" есть ли гарантия, что сперва будут инициализированы все простые типы, а лишь потом сложные?. Я знаю, что порядок между модулями не определён, а внутри модуля в порядке описания (если не использовано явное указание компилятору на то, что должно был инициализировано сначала). Но тогда легко получается вышеописанная ситуация. В данном примере я заменил std:string на обычный массив и он стал инициализироваться перед инициализацией классов. В принципе, насколько я помню, секция .data как раз и хранит значения глобальных переменных, а секция .text константы. Следовательно, при запуске эти секции уже есть в программе и они уже инициализированы задолго до вызовов конструкторов любых сложных объектов.

 5 
 : Августа 14, 2018, 07:19:27 pm 
Автор kim - Последний ответ от da-nie
я поставил Mate. Smiley Меня просто достала windows 7 (я мог бы и XP поставить, но решил в качестве эксперимента всё же перейти хотя бы на семёрку). Она просто неудобная. Тупой проводник без кнопки 'на уровень выше',часто забывающий переключать папку по одинарному щелчку. Тормоза Firefox. Испорченный Paint. Нет, пора на Linux возвращаться после десятилетнего перерыва. Smiley Правда, вот чего я в линуксах не люблю, так это постоянные изменения с каждым обновлением. Я всё же люблю стабильность... Ну и система пакетов меня раньше доводила до белого каления, когда в системе половина мусора, который используют 1.5 приложения, а этот мусор тащит свои зависимости разных версий. Ставишь из тарбола программу, а ей ещё 100 пакетов надо, а им ещё, а ещё один не совместим с тем, что уже есть. Тут хоть apt работает автоматически. Вроде бы. Smiley

Цитировать
Ну а окружений рабочего стола - пактически в любом линухе на любой вкус и цвет.

Игра в конструктор меня не прельщает. Потому я и не ставил gentoo. Smiley

 6 
 : Августа 14, 2018, 05:25:39 pm 
Автор kim - Последний ответ от PoP
Видимо - Cinnamon больше похожа на XP  Smiley.
А так - всё практически тоже, только в профиль.
В основе Ubuntu - ветка unstable  Debian. Свежее общее ПО, главное - драйвера под новое железо появляются раньше. Встречаются коммерческие и не GPL программы в центре приложений. Естественно - слегка меньше стабильность.
Mint основан на Ubuntu, использует репозитории Ubuntu основные изменения - простота начальной установки и окружение по умолчанию.

 7 
 : Августа 14, 2018, 03:27:54 pm 
Автор kim - Последний ответ от da-nie
Не, Debian такая же, как и Ubuntu.
Я Mint поставил. Он мне понравился. Smiley

 8 
 : Августа 14, 2018, 02:36:50 pm 
Автор kim - Последний ответ от PoP
Не всегда ведь проект делается в IDE. Да и вот свежий пример: решил-таки Linux поставить. Смотрим, что у нас есть из популярного:
Fedora
Mint
Ubuntu
OpenSuSe
Mageia
Astra Linux
Debian ?
Если не устраивает новомодная systemd - есть форк с system V.
Если не издеваться над ней подключая репозитории testing - стабильна до безобразия.
Ну а окружений рабочего стола - пактически в любом линухе на любой вкус и цвет.

 9 
 : Августа 13, 2018, 05:59:19 pm 
Автор kim - Последний ответ от da-nie
Цитировать
Она была в dos.h, которого под unix-ами нет

Логично. Smiley Просто delay находится в unistd. А "<unistd.h> содержит различные основные функции и константы POSIX". Потому я и думал, что она везде, где POSIX есть должна быть.

Цитировать
Вы, наверное, с QNX 6.6 путаете, там как раз Photon нет.

Наверное. Я дальше 6.5 не смотрел. Smiley

Цитировать
Вероятно должно. На какие-то ЕС1866 ставится. Они же разные бывают по начинке, да?

Судя по буклету, по которому заказывали, там вариативность небольшая.

 10 
 : Августа 13, 2018, 04:46:27 pm 
Автор kim - Последний ответ от ob1
Цитировать
Вместо QNX 6.5 вам бы закупить ЗОСРВ «Нейтрино».

А ПО для QNX 6.3 на нём работает? Или там Qt и от фотона одни воспоминания? Smiley

Смотря какое ПО. В целом работает. Там Photon, а в нём можно Qt и десктопный OpenGL. Вы, наверное, с QNX 6.6 путаете, там как раз Photon нет.

Ну и главная головная боль - ставится и работает ли оно на таком чуде, как бывшая ЕС-1866, а ныне Уран-2.

Вероятно должно. На какие-то ЕС1866 ставится. Они же разные бывают по начинке, да?

Страниц: [1] 2 3 ... 10