Это хорошая практика, чтобы сделать геттеры и сеттеры рядный?


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

On Изучать C++, Они сказали, что он будет работать быстрее. Итак, я подумал, что было бы здорово использовать на геттерах и сеттерах. Но, может быть, в этом есть какие-то недостатки?

11 64

11 ответов:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

удачи.

Шейн

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

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

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

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

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

встроенное ключевое слово бессмысленно в вашем случае

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

ключевое слово inline влияет на связывание, а не на встраивание. Это немного запутанно, но Читайте об этом.

Если определение находится в другой единице компиляции (исходный файл после препроцессора, в основном), чем вызов, встраивание будет возможно только в том случае, если вся оптимизация проекта и генерация кода времени связи включен. Включение его значительно увеличивает время связывания (так как он практически повторно компилирует все в компоновщике), но, очевидно, может улучшить производительность. Не уверен, что он включен или выключен по умолчанию в GCC и VS.

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

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

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

принять, что пуристы. : -)