Выполненный код перед каждым вызовом функции для класса в C++

Кажется, есть три решения этой проблемы (все с плюсами и минусами).

Решение 1: Кнопка в форме.

Но проблема в том, что в некоторых версиях популярных браузеров, таких как Chrome, Safari и Internet Explorer, он добавляет знак вопроса в конце URL. Другими словами, код выше вашего URL будет выглядеть примерно так:

http://someserver/pages2?

Есть один способ исправить это, но это потребует настройки на стороне сервера. Одним из примеров использования Apache Mod_rewrite было бы перенаправить все запросы с завершающим ? на их соответствующие URL-адреса без ?. Вот пример использования .htaccess, но здесь есть полный поток :

RewriteCond %{THE_REQUEST} \?\ HTTP [NC]
RewriteRule ^/?(index\.cfm)? /? [R=301,L]

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

Плюсы:

  1. Это настоящая кнопка, и семантически это имеет смысл.
  2. Поскольку это настоящая кнопка, она также будет действовать как настоящая кнопка (например, перетаскиваемое поведение и / или имитировать щелчок при нажатии клавиши пробела, когда она активна).
  3. Нет JavaScript, не требуется сложный стиль.

Минусы:

  1. Трейлинг ? выглядит некрасиво в некоторых браузерах. Это может быть исправлено хаком (в некоторых случаях), использующим POST вместо GET, но чистый способ - перенаправление на стороне сервера. Недостатком перенаправления на стороне сервера является то, что он вызовет дополнительный HTTP-вызов для этих ссылок из-за перенаправления 304.
  2. Добавляет дополнительный элемент
  3. Позиционирование элемента при использовании нескольких форм может быть сложным и становится еще хуже при работе с адаптивными дизайнами. Некоторое расположение может стать невозможным для этого решения в зависимости от порядка элементов. Это может в конечном итоге повлиять на удобство использования, если на эту задачу повлияет дизайн.

Решение 2. Использование JavaScript.

Вы можете использовать JavaScript для запуска onclick и других событий, чтобы имитировать поведение ссылки с помощью кнопки. Приведенный ниже пример можно улучшить и удалить из HTML, но он просто иллюстрирует идею:


Плюсы:

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

Минусы:

  1. Требуется JavaScript, что означает менее доступный. Это не идеально для базового (основного) элемента, такого как ссылка.

Решение 3. Якорь (ссылка) в стиле кнопки.

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

Плюсы:

  1. Простая (для базовых требований) и хорошая кросс-браузерная поддержка.
  2. Не нужно для работы.
  3. Для работы не требуется JavaScript.

Минусы:

  1. Семантика не работает, потому что вы хотите кнопку, которая действует как ссылка, а не ссылка, которая действует как кнопка.
  2. Он не будет воспроизводить все варианты поведения решения № 1. Он не будет поддерживать то же поведение, что и кнопка. Например, ссылки перетягиваются по-разному при перетаскивании. Также триггер ссылки «пробел» не будет работать без дополнительного кода JavaScript. Это добавит много сложности, так как браузеры не согласуются с тем, как они поддерживают keypress события на кнопках.

Заключение

Решение № 1 (кнопка в форме ) кажется наиболее прозрачным для пользователей с минимальными затратами труда. Если этот выбор не влияет на ваш макет и возможна настройка на стороне сервера, это хороший вариант для случаев, когда доступность является главным приоритетом (например, ссылки на странице ошибок или сообщения об ошибках).

Если JavaScript не является препятствием для ваших требований доступности, то решение № 2 ( JavaScript ) предпочтительнее, чем № 1 и № 3.

Если по какой-то причине доступность является жизненно важной (JavaScript не является опцией), но вы находитесь в ситуации, когда ваш дизайн и / или конфигурация вашего сервера не позволяют использовать опцию № 1, тогда решение № 3 ( Якорь, стилизованный под кнопку ), является хорошей альтернативой для решения этой проблемы с минимальным влиянием на удобство использования.

7
задан Mechanical snail 22 July 2012 в 22:21
поделиться

8 ответов

AspectC ++ - это то, что вам нужно. Я сам не использовал его, но парадигма аспектно-ориентированного программирования пытается решить именно эту проблему.

8
ответ дан 6 December 2019 в 10:52
поделиться

Я бы предложил использовать идиому невиртуального интерфейса. Все публичные функции не виртуальные. Все виртуальные функции являются защищенными или частными. Открытые члены делегируют вызовы виртуальным членам и обычно реализуются как встроенные функции.

Именно так IOStreams реализованы в STL. Вы можете узнать больше об этом в Викиучебниках C ++ .

Цель: преобразовать в модули / реорганизовать общие до и после фрагментов кода (например, проверка инварианта, получение / снятие блокировок) для всей иерархии классов в одном месте .

С уважением,
Ованес

3
ответ дан 6 December 2019 в 10:52
поделиться

Следующее может показаться излишним, но как насчет?

http://msdn.microsoft.com/en-us/library/c63a9b7h.aspx

3
ответ дан 6 December 2019 в 10:52
поделиться

Еще одна вещь, которую вы могли бы рассмотреть, - это использовать что-то вроде [boost / C ++ 0X] оболочка shared_ptr, в которой вы вызываете свою пользовательскую функцию в перегрузке '->' перед возвратом указателя экземпляра класса. Он включает изменение использования, но не базового класса, и я использовал его пару раз для достижения того же эффекта. Еще одна мысль.

2
ответ дан 6 December 2019 в 10:52
поделиться

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

1
ответ дан 6 December 2019 в 10:52
поделиться

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

Например:

class Base {
  public:
    void MyMethod(void) { /* Insert code here */ YourMethod(); }
  protected:
    virtual void YourMethod(void) {}
};

Если разработчик знает, что у него есть определенный подкласс, он все равно может обойти ваш код, просто используя dynamic_cast и используя свой собственный набор методов. Таким образом, вы можете следовать другим уже опубликованным предложениям, которые не связаны с базовым языком C ++.

1
ответ дан 6 December 2019 в 10:52
поделиться

Похоже на то, что делает профилировщик. Вы искали в источнике инструменты профилирования?

0
ответ дан 6 December 2019 в 10:52
поделиться

Вы также можете сделать это с помощью Любопытно повторяющегося шаблона шаблона (CRTP) .

0
ответ дан 6 December 2019 в 10:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: