Перейти к содержанию
    

Как бы правильно отработать такую ситуацию на С++:

Есть плата, на которую может устанавливаться два-три близких по системе команд GSM-модема (большинство нужных команд полностью идентичны).

Думаю делать так:

Создать класс содержащий все нужные функции (различающиеся команды объявить как виртуальные), от него создать нужное количество наследников с переопределёнными функциями и .

Тип модема может задаваьтся конфигурацией (байт в еепром) или определятся запросом версии AT-командой (предпочтительней).

А вот как дальше делать?

Как лучше объявить в программе переменную-наследника?

Компилятор IAR AVR.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Направление мысли правильное. Фабрика вам в помощь. Если есть возможность использовать динамическую память , то вообще без проблем. Если нет - статический буфер достаточного размера, чтоб вместить самого большого наследника и placement new.

Изменено пользователем neiver

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если есть возможность использовать динамическую память , то вообще без проблем.

 

Не использовал пока динамическую память, нода смотреть как с этим в IAR AVR.

 

статический буфер достаточного размера, чтоб вместить самого большого наследника и placement new

 

Получается по смыслу что-то аналогичное Сишному union-у?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Получается по смыслу что-то аналогичное Сишному union-у?

Нет. Просто статически выделяется буфер в памяти и в нем конструируется (с помощью конструктора) объект нужного типа.

char buffer[MAX_BUFFER_SIZE]; // static array
...
class Base{...};
class D1 :public Base {...};
class D2 :public Base {...};
class D3 :public Base {...};
...

Base *ProduceObject(ObjectType type)
{
   switch(type)
   {
       case Type1: return new (buffer) D1(); // creating an object using palcement new
       case Type2: return new (buffer) D2();
       case Type3: return new (buffer) D3();
   }
}

 

Да, еще возможно придётся определить оператор new если он еще не определен:

void *operator new(unsigned int size, void* ptr)
{
    return ptr;
}

В этом операторе можно что-то сделать с буфером памяти, обнулить его, например, а можно ничего не делать.

Изменено пользователем neiver

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нет. Просто статически выделяется буфер в памяти и в нем конструируется (с помощью конструктора) объект нужного типа.

char buffer[MAX_BUFFER_SIZE]; // static array
...
class Base{...};
class D1 :public Base {...};
class D2 :public Base {...};
class D3 :public Base {...};
...

Base *ProduceObject(ObjectType type)
{
   switch(type)
   {
       case Type1: return new (buffer) D1(); // creating an object using palcement new
       case Type2: return new (buffer) D2();
       case Type3: return new (buffer) D3();
   }
}

 

Да, еще возможно придётся определить оператор new если он еще не определен:

void *operator new(unsigned int size, void* ptr)
{
    return ptr;
}

В этом операторе можно что-то сделать с буфером памяти, обнулить его, например, а можно ничего не делать.

 

Что-то всё равно не так.

Ввёл:

char buffer[1000]; // static array

class Base {
public:
    unsigned int A;
    unsigned int N;
    void SetA(unsigned int a)
    {
        A=a;
    }
};
class D1 :public Base {
public:
    void *operator new(unsigned int size, void* ptr)
    {
    }
    void SetN()
    {
        N=0;
    }
};
class D2 :public Base {
public:
    void SetN()
    {
        N=1;
    }
};
class D3 :public Base {
public:
    void SetN()
    {
        N=2;
    }
};

Base *ProduceObject(unsigned char type)
{
    switch(type)
    {
    case 0: return new (buffer) D1(); // creating an object using palcement new
    case 1: return new (buffer) D2();
    case 2: return new (buffer) D3();
    }
}
int _tmain(int argc, _TCHAR* argv[])
{


    Base *p;
    p=ProduceObject(0);
    p->SetA(10);
}

Компилятор говорит:

error C2660: 'operator new' : function does not take 2 arguments

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Что-то всё равно не так.
Так вы operator new объявили членом D2, а надо его сделать членом Base. А еще можно buffer и фабрику также спрятать внутрь base, сделав статическим членом и статической функцией соответственно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Так вы operator new объявили членом D2, а надо его сделать членом Base.

Да, не заметил. Спасибо.

 

А еще можно buffer и фабрику также спрятать внутрь base, сделав статическим членом и статической функцией соответственно.

 

Попробую.

 

Проверял в Visual Studio (ничего другого под рукой нет).

Как считаете в IAR AVR так же всё будет работать?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Создать класс содержащий все нужные функции (различающиеся команды объявить как виртуальные), от него создать нужное количество наследников с переопределёнными функциями и .

......

 

ИМХО, тут можно конечно сделать, но из за 2-x, 3-x подобных устройств использовать С++ со своими возможностями ООП (виртуальные функции и полиморфизм) Вам больше навредит, чем поможет. Сильно не рационально. С++ надо использовать только там, где это действительно необходимо и приемлемо, а не просто ради того чтоб использовать. Вот если бы подобных устройств было десятки, еще можно говорить….

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ИМХО, тут можно конечно сделать, но из за 2-x, 3-x подобных устройств использовать С++ со своими возможностями ООП (вирртуальные функции и полиморфизм) вам больше навредит, чем поможет. Сильно не рационально. С++ надо использовать только там, где это действительно необходимо и рационально, а не просто ради того чтоб использовать. Вот если бы подобных устройств было десятки, еще можно говорить….

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

К тому-же как это можно реализовать без полиморфизма?

С помощью таблиц функций? Вручную их заполнять нужными значениями и т.д. Получаются те-же виртуальные функции, только самописные и кривые - восход солнца вручную.

Вставлять в местах где поведение устройств ветвления по типу устройства? Еще более неудобно и черевато дополнительными ошибками.

Так, что выбранный путь очень даже рационален. Виртуальные функции дешевы и удобны.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ИМХО, тут можно конечно сделать, но из за 2-x, 3-x подобных устройств использовать С++ со своими возможностями ООП (виртуальные функции и полиморфизм) Вам больше навредит, чем поможет. Сильно не рационально. С++ надо использовать только там, где это действительно необходимо и приемлемо, а не просто ради того чтоб использовать. Вот если бы подобных устройств было десятки, еще можно говорить….

В смысле?

Что значит "десятки устройств"?

Десятки типов устройств?

Или экземпляров?

 

Типов модулей может быть 2-3-..5..10(это точно перебор, да и 5 - перебор: 2-3, а дальше - много(слишком))

А модулей - сотни(чем больше тем лучше) каждого типа...

 

У как по-Вашему лучше сделать?

 

С++ надо использовать только там, где это действительно необходимо и приемлемо, а не просто ради того чтоб использовать

 

честный ответ - как глоток свежего воздуха...©

А где ж его использовать?(С++, в смысле)...?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

..А где ж его использовать?(С++, в смысле)...?

 

ну уж точно не в МК :) покрайней мере пока не стоит в полной мере. а вот ООА необходимо юзать всегда. даже когда вы пишите на азме. при этом сама механизация того или иного функционала - уже вторично.

 

(круглый)

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ну уж точно не в МК :) покрайней мере пока не стоит в полной мере.

Поясните, пожалуйста, какие именно аспекты С++ делают его нерекомендуемым для использования с МК?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

...какие именно аспекты С++ делают его нерекомендуемым для использования с МК?

 

для этого надо сначала понять, какие плюсы Вы видите в его использовании?

 

только без взгляда под углом, что это можно сделать. Сделать можно ВСЁ...

а вот плюсы...с этим уже поконкретней.

 

(круглый)

ЗЫ

Всегда надо идти от задачи. Лично мне не известны такие задачи где требуется си плас плас под МК. За исключением не анжинерных задач - типа попилить бабло. Но это мы не бум рассматривать надеюсь...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В смысле?

Что значит "десятки устройств"?

Десятки типов устройств?

Или экземпляров?

 

Разумеется типов, Вы же сами писали: "два-три близких по системе команд GSM-модема".

 

У как по-Вашему лучше сделать?

На чистом Си, нет никаких проблем.

 

 

Не хочу переводить тему в категорию Си vs C++. Сам пишу софт в основном для ПК, на С++. В микроконтроллере мне С++ понадобился 1 раз, кода писал приложение для TFT панели, писал свой GUI. Тут С++ со своими возможностями ООП ”рулит”.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Лично мне не известны такие задачи где требуется си плас плас под МК.
Лично мне не известны такие задачи, где требуется что угодно, кроме текстового редактора (набирать вручную HEX-файлы). Этого, в принципе, достаточно. Мнемокод — уже счастье. Ассемблер, да если еще и с макросами — рай земной.

 

нужно человеку буханка хлеба и четверть ведра воды в день, всего остального ему хочется» © забыл чей)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

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

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...