Это хорошая практика, чтобы сделать геттеры и сеттеры встроенными? - PullRequest
69 голосов
/ 10 июня 2010
public:
     inline int GetValue() const {
          return m_nValue;
     }
     inline void SetValue(int nNewValue) {
          this -> m_nValue = nNewValue;
     }

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

Ответы [ 11 ]

55 голосов
/ 10 июня 2010

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

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

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

29 голосов
/ 10 июня 2010

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

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

16 голосов
/ 10 июня 2010

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

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

10 голосов
/ 10 июня 2010

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

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

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

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

5 голосов
/ 11 июня 2010

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

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

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

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

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

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

Удачи.

Шейн

2 голосов
/ 10 июня 2010

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

2 голосов
/ 10 июня 2010

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

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

1 голос
/ 01 декабря 2015

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

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

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

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

1 голос
/ 11 июня 2010

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

1 голос
/ 10 июня 2010

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

...