crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )


  Ответ в Статический полиморфизм
Введите ваше имя
Подтвердите код

Введите в поле код из 6 символов, отображенных в виде изображения. Если вы не можете прочитать код с изображения, нажмите на изображение для генерации нового кода.
Теги
Выровнять по центру
Ссылка на тему
Ссылка на сообщение
Скрытый текст
Сокращение
Код с подсветкой
Offtopic
 
Удалить форматирование
Спец. элементы
Шрифт
Размер
 
Цвет шрифта
 
Отменить ввод
Вернуть ввод
Полужирный
Курсив
Подчеркнутый
 
 
Смайлики
Вставить изображение
Вставить адрес электронной почты
Цитата
Код
Раскрывающийся текст
 
Увеличить отступ
По левому краю
По центру
По правому краю
Вставить список
Вставить список

Опции сообщения
 Включить смайлы?
Иконки сообщения
(Опционально)
                                
                                
  [ Без иконки ]
 


Последние 10 сообщений [ в обратном порядке ]
Warburst Дата 10.4.2025, 1:18
  и то верно
Awaken Дата 10.4.2025, 0:57
  не очень полезные
AlexandrVol Дата 9.9.2023, 0:18
  Кста, полезные курсы для программирования на c# можно найти на ggsel

Кста, полезные курсы для программирования на c# можно найти на ggsel
Алексей1153 Дата 2.1.2021, 13:12
  Litkevich Yuriy, можно сказать, что ничем, но в редких случаях компилятор может перепутать с синтаксисом вызова или объявления функции. Со списком инициализации всё всегда однозначно
Litkevich Yuriy Дата 2.1.2021, 1:22
 
Цитата(Алексей1153 @ 31.12.2020, 14:03) *
Pin{} - создание экземпляра класса Pin с конструктором по умолчанию
чем отличается от традиционного Pin() ?
Алексей1153 Дата 31.12.2020, 12:03
 
Цитата(Litkevich Yuriy @ 30.12.2020, 14:10) *
что значит using в этом месте

объявление алиаса (более удобная замена typedef)

Цитата(Litkevich Yuriy @ 30.12.2020, 14:10) *
почему здесь Pin с фигурными скобками


{} - пустой список инициализации

Pin{} - создание экземпляра класса Pin с конструктором по умолчанию

ControlWay{Pin{}} - создание экземпляра класса ControlWay, конструктор принимает ссылку на объект класса Pin

union тут не используется
Litkevich Yuriy Дата 30.12.2020, 12:10
 
Цитата(Алексей1153 @ 30.12.2020, 11:18) *
using ControlWay=std::variant<EmptyDevice,Pin,UART,SoftUART>;
что значит using в этом месте?

Цитата(Алексей1153 @ 30.12.2020, 11:18) *
m_DeviceList.addDevice(new ControlWay{Pin{}});
почему здесь Pin с фигурными скобками?
Если я правильно понял, то ControlWay с фигурными потому что он union или нет?
Алексей1153 Дата 30.12.2020, 9:18
  https://onlinegdb.com/r1J-2ctTv

#include <iostream>
#include <variant>
#include <algorithm>
#include <vector>

class EmptyDevice
{
public:
    void print_me()const
    {
        std::cout<<"EmptyDevice"<<'\n';
    }
};

class Pin
{
public:
    void print_me()const
    {
        std::cout<<"Pin"<<'\n';
    }
};

class UART
{
public:
    void print_me()const
    {
        std::cout<<"UART"<<'\n';
    }
};

class SoftUART
{
public:
    void print_me()const
    {
        std::cout<<"SoftUART"<<'\n';
    }
};


using ControlWay=std::variant<EmptyDevice,Pin,UART,SoftUART>;


class DeviceList
{
    std::vector<ControlWay*> m_list;
public:
    bool addDevice(ControlWay* device)
    {
        m_list.push_back(device);
        return true;
    }
    
    bool removeDevice(ControlWay* device)
    {
        m_list.erase(std::remove(m_list.begin(),m_list.end(),device),m_list.end());
        return true;
    }
    
    void print_me()const
    {
        for(auto* d:m_list)
        {
            std::visit([](auto& device)
            {
                device.print_me();
            },*d);
        }
    }
};

int main()
{
    DeviceList m_DeviceList;
    
    m_DeviceList.addDevice(new ControlWay{Pin{}});
    m_DeviceList.addDevice(new ControlWay{UART{}});
    m_DeviceList.addDevice(new ControlWay{SoftUART{}});

    m_DeviceList.print_me();
    
    //m_DeviceList.removeDevice(d1);
    //m_DeviceList.removeDevice(d2);
    //m_DeviceList.removeDevice(d3);
    
    //не забыть сделать освобождение памяти либо заюзать std::unique_ptr

    return 0;
}


Цитата
Pin
UART
SoftUART
Алексей1153 Дата 30.12.2020, 8:34
 
Цитата
но наличие виртуальных функций для микроконтроллерного применения - плохо.
это замедляет код и раздувает его из-за vtable.


немного замедлит (вряд ли заметно), но не раздует. А вот шаблоны раздуют программный код сильно. И отлаживать их будет сложнее. Компилить дольше тоже.

А стандарт C++ какой?

Если 17, то std::variant подойдёт


если что, реализацию std::variant можно найти, если компилятор его ещё не умеет )
Litkevich Yuriy Дата 30.12.2020, 7:53
  Пытаюсь понять, как можно в С++ реализовать полиморфизм времени компиляции для следующей задачи.

Имеется шина 1-Wire (из названия понятно, что она однопроводная, несчитая общего проводника).
Имеется N устройств на этой шине.
Шина должна знать какие устройства на ней есть.
Устройства должны знать на какой шине сидят.
Устройства пользуются функциями-членами шины для выполнения своих задач.


class OneWireDevice;

class OneWire
{
    bool addDevice(OneWireDevice *device);
    bool removeDevice(OneWireDevice *device);
    
    List<OneWireDevice *> deviceList(); // List - предполагаемый шаблонный контейнерный класс
    
    void foo();
}

class OneWireDevice
{
    OneWireDevice(OneWire *awire = 0);
    
    OneWire* wire();
    
    void bar()
    {
        wire()->foo();
    }
}



Особенность 1-Wire:
1) может быть реализована програмным дрыганьем ножки микроконтроллера;
2) может быть реализована через аппаратный UART, т.е. передавая определённый байт
огибающая сигнала будет повторять необходимую форму ипульсов 1-Wire.
3) сам UART можно реализовать программно дрыгая ножку микроконтроллера.

Т.о. возможны следующие схемы реализации 1-Wire:
OneWire(Pin);
OneWire(UART);
OneWire(SoftUART(Pin));

Сейчас у меня сделан абстрактный класс 1-Wire и наследники, реализующие один из 3-х способов.

class OneWire {...};

// -1-
class OneWirePin: public OneWire
{
    OneWirePin(Pin *pin);
};

//...
Pin *pin = new Pin();
OneWirePin *wire(pin);    


// -2-
class OneWireUart: public OneWire
{
    OneWireUart(Uart *uart);
};

//...
Uart *uart = new Uart();
OneWirePin *wire(uart); 

// -3-
class OneWireUartPin: public OneWire
{
    OneWireUartPin(SoftUart *uart)
};

//...
Pin *pin = new Pin();
SoftUart *uart = new SoftUart(pin);
OneWirePin *wire(uart);



// ======================================

Всё бы хорошо, но наличие виртуальных функций для микроконтроллерного применения - плохо.
это замедляет код и раздувает его из-за vtable. Сначала хотел реализовать OneWire на шаблонах.

Однако споткнулся на том, что класс OneWireDevice должен пользоваться OneWire и, в частности, возвращать OneWire.
т.е. сделать сам OneWire шаблонным не получится, т.к. для метода OneWireDevice::wire() надо будет аргумент шаблона указывать.

Может кому-то подобную иерархию со статическим полиморфизмом доводилось реализовывать?


В идеале хотелось бы получить такой код применения:
// -1-
Pin *pin = new Pin();
OneWire *wire = new OneWire<Pin *>(pin);

// или

Pin pin;
OneWire *wire = new OneWire<Pin>(pin);


// -2-
UART *uart = new Uart();
OneWire *wire = new OneWire<UART *>(uart);

// или

UART uart;
OneWire *wire = new OneWire<UART >(uart );


// -3-
SoftUART *uart = new SoftUART();
OneWire *wire = new OneWire<SoftUART *>(uart);

// или

SoftUART uart;
OneWire *wire = new OneWire<SoftUART>(uart );
Просмотр темы полностью (откроется в новом окне)
RSS Рейтинг@Mail.ru Текстовая версия Сейчас: 10.7.2025, 22:14