Это - хорошая практика для создания методов считывания и методов set встроенными?

public:
     inline int GetValue() const {
          return m_nValue;
     }
     inline void SetValue(int nNewValue) {
          this -> m_nValue = nNewValue;
     }

На Изучают C++, они сказали, что он будет работать быстрее. Так, я думал, что будет замечательно использовать на методах считывания и методах set. Но возможно, существуют некоторые недостатки к нему?

70
задан Martijn Courteaux 9 August 2017 в 13:54
поделиться

10 ответов

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

Компилятор C ++ очень умен и почти наверняка автоматически встроит такую ​​простую функцию, как эта. И, как правило, он умнее вас и гораздо лучше определяет, что следует или не следует встраивать.

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

58
ответ дан 24 November 2019 в 13:26
поделиться

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

Кстати, вы можете пропустить встроенный , если вы реализуете непосредственно в определении класса.

2
ответ дан 24 November 2019 в 13:26
поделиться

Это плохая практика в общедоступных API. Любое изменение этих функций требует перекомпиляции всех клиентов.

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

16
ответ дан 24 November 2019 в 13:26
поделиться

Если вы напишете их внутри определения, они будут считаться встроенными по умолчанию .

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

29
ответ дан 24 November 2019 в 13:26
поделиться

Отрицательные моменты:

  1. Компилятор может вас игнорировать.

  2. Любое изменение этих функций требует перекомпиляции всех клиентов.

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

10
ответ дан 24 November 2019 в 13:26
поделиться

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

1
ответ дан 24 November 2019 в 13:26
поделиться

Помещая код в заголовок, вы раскрываете свою внутреннюю работу класса. Клиенты могут это увидеть и сделать предположения о том, как работает ваш класс. Это может затруднить последующее изменение вашего класса без нарушения клиентского кода.

2
ответ дан 24 November 2019 в 13:26
поделиться

Я также хотел бы добавить, что если вы не выполняете миллионы get/set на кадр, то практически не имеет значения, инлайнятся они или нет. Честно говоря, не стоит из-за этого терять сон.

Кроме того, имейте в виду, что если вы поставили слово 'inline' перед декларацией+определением, это не значит, что компилятор будет инлайнить ваш код. Он использует различные эвристики, чтобы определить, имеет ли это смысл, что часто является классическим компромиссом между скоростью и размером. Однако есть ключевое слово '__forceinline', которое используется в VC++ (я не уверен, что оно есть в GCC), которое перечеркивает эвристику компилятора. Я действительно не рекомендую это делать, и, кроме того, когда вы перейдете на другую архитектуру, это, скорее всего, будет неправильно.

Постарайтесь поместить все определения функций в файл реализации, а чистые декларации оставьте для заголовков (если, конечно, вы не метапрограммируете шаблоны (STL/BOOST/etc), в этом случае почти все будет в заголовках ;))

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

О, и еще один момент, если вы чувствуете, что вам действительно нужно, чтобы класс был больше данными, чем кодом, подумайте об использовании старого доброго struct, который не приносит с собой OO багаж абстракции, для этого он и существует. :)

Извините, не хотел так много говорить, но я просто думаю, что это помогает рассмотреть реальные случаи использования в реальном мире, и не зацикливаться на педантичных настройках компилятора (поверьте мне, я был там ;))

Удачи.

Shane

5
ответ дан 24 November 2019 в 13:26
поделиться

Не надо, начинайте доверять компиляторам, по крайней мере, для таких оптимизаций!
«Но не всегда»

1
ответ дан 24 November 2019 в 13:26
поделиться

Должен сказать, я не испытывают сильное отвращение к этой практике, которое, похоже, испытывают другие участники этой беседы. Я согласен с тем, что прирост производительности от встраивания незначителен во всех случаях, кроме наиболее часто используемых. (И да, я встречал такие случаи на практике.) Когда я делаю такой вид встраивания, я делаю это для удобства и обычно только для однострочников, подобных этому. В большинстве моих случаев использования необходимость избегать перекомпиляции на стороне клиента, если я когда-либо их изменяю, просто не так уж сильна.

Да, вы можете удалить встроенный , поскольку это подразумевается размещением реализации.

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

Возьмите это, пуристы. : -)

0
ответ дан 24 November 2019 в 13:26
поделиться
Другие вопросы по тегам:

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