Хорошая практика - сделать геттеры и сеттеры встроенными?
public:
inline int GetValue() const {
return m_nValue;
}
inline void SetValue(int nNewValue) {
this -> m_nValue = nNewValue;
}
В Learn С++ они сказали, что он будет работать быстрее. Итак, я подумал, что было бы здорово использовать на геттерах и сеттерах. Но, может быть, есть некоторые недостатки?
Ответы
Ответ 1
Я не встраиваю ничего, пока профайлер не сказал мне конкретно, что не встраивание приводит к проблемам с производительностью.
Компилятор С++ очень умный и почти наверняка автоматически включит такую простую функцию, как это для вас. И, как правило, это умнее, чем вы, и будет намного лучше определять, что должно или не должно быть встроено.
Я бы не стал думать о том, что делать или нет, и сосредоточиться на решении. Добавление ключевого слова inline
позже (что не является гарантией встроенного BTW) очень легко сделать, и потенциальные места можно легко найти с помощью профилировщика.
Ответ 2
Если вы пишете их внутри определения, они считаются inline
по умолчанию.
Это означает, что они будут разрешены в нескольких единицах компиляции (поскольку сами определения классов обычно появляются в нескольких единицах компиляции), а не в том, что они действительно будут встроены.
Ответ 3
Это плохая практика в публичном API. Любое изменение этих функций требует перекомпиляции всех клиентов.
В целом, у которого получатели и сеттеры демонстрируют плохую абстракцию, не делайте этого.
Если вы постоянно переходите к исходным данным в другом классе, вам, скорее всего, нужно будет упорядочить свои классы, вместо этого рассмотрите, как вы хотите манипулировать данными в классе и предоставить соответствующие методы для этого.
Ответ 4
Отрицательные моменты:
-
Компилятор может игнорировать вас.
-
Любое изменение этих функций требует перекомпиляции всех клиентов.
-
Хороший компилятор будет встраивать не-встроенные функции в любом случае, когда это подходит.
Ответ 5
Я также хотел бы добавить, что, если вы не выполняете миллионы запросов/наборов на фрейм, это почти не имеет значения, являются ли они вложенными или нет. Честно говоря, не стоит терять сон.
Кроме того, имейте в виду, что только потому, что вы помещаете слово "inline" перед вашим объявлением +, не означает, что компилятор будет встроить ваш код. Он использует различные эвристики, чтобы понять, имеет ли это смысл, что часто является классическим компромиссом скорости и размера. Однако существует ключевое слово грубой силы "__forceinline", находящееся в заключении в VС++ (я не уверен, что это такое в GCC), которое топает в компиляторах с эвристикой. Я действительно не рекомендую его вообще, и, кроме того, если вы перейдете к другой архитектуре, это, скорее всего, будет неверным.
Попробуйте поместить все определения функций в файл реализации и оставить чистые объявления для заголовков (если, конечно, вы не метапрограммируете шаблон (STL/BOOST/etc), и в этом случае почти все в заголовках;))
Одно из классических мест, в которые люди любят встроить (по крайней мере, в видеоигры, откуда я), находится в заголовках математики. Кросс/точечные продукты, длины векторов, очистка матрицы и т.д. Часто помещаются в заголовок, который, как мне кажется, не нужен. 9/10, это не имеет никакого значения для производительности, и если вам когда-либо понадобится выполнить жесткий цикл, например, преобразование большого векторного массива по какой-либо матрице, вам, вероятно, лучше вручную выполнить встроенную математику или даже лучше ее кодировать платформенный ассемблер.
О, и еще один момент, если вы чувствуете, что вам действительно нужен класс, чтобы быть больше данных, чем код, подумайте о том, чтобы использовать добрую старую структуру, которая не несет в себе багаж OO с абстракцией, что он там.:)
Извините, это не значит, что так много, но я просто думаю, что это помогает рассматривать случаи использования в реальном мире и не слишком зависеть от настроек педантичного компилятора (поверьте мне, я был там;))
Удачи.
Шейн
Ответ 6
Код будет компилироваться немного дольше, и вы потеряете инкапсуляцию. Все зависит от размера проекта и его характера. В большинстве случаев это нормально, если они не имеют сложной логики.
Кстати, вы можете пропустить inline
, если вы реализуете непосредственно в определении класса.
Ответ 7
Поместив код в заголовок, вы подвергаете свою внутреннюю работу. Клиенты могут видеть это и делать предположения о том, как работает ваш класс. Это может затруднить изменение вашего класса позже, не нарушая код клиента.
Ответ 8
Я бы сказал, что вам не нужно беспокоиться об этом. Прочтите раздел часто задаваемых вопросов о встраивании.
Ответ 9
Не нужно, начинайте доверять компиляторам, по крайней мере для таких оптимизаций!
"Но не всегда"
Ответ 10
Ключевое слово inline не имеет смысла в вашем случае
Компилятор будет встроить вашу функцию, если она может и хочет, независимо от ключевого слова.
Ключевое слово inline влияет на привязку, а не на inline. Это немного запутанно, но читайте на нем.
Если определение находится в другом модуле компиляции (исходный файл после препроцессора, в основном), чем вызов, вложение будет возможно только в том случае, если включена оптимизация всего проекта и генерация кода времени ссылки. Включение этого значительно увеличивает время связывания (поскольку оно практически перекомпилирует все в компоновщике), но, очевидно, может повысить производительность. Не уверен, что он включен или выключен по умолчанию в GCC и VS.
Ответ 11
Я должен сказать, что у меня нет сильного отвращения к этой практике, которую, похоже, есть у других в этой теме. Я согласен с тем, что выигрыш в производительности от inlining незначительно во всех, но наиболее часто используемых случаях. (И да, я столкнулся с такими случаями на практике.) Там, где я делаю такую вставку, я делаю это для удобства и вообще для однострочных. В большинстве моих случаев использования необходимость избегать перекомпиляции на стороне клиента, если я когда-либо меняю их, не так уж сильна.
Да, вы можете отказаться от inline
, как это подразумевается при размещении реализации.
Кроме того, я немного удивлен тем, что я против аксессоров. Вы вряд ли можете чихать в классе на любом языке OO, не выдувая несколько слов, и они, в конце концов, являются правильной методикой абстрагирования реализации от интерфейса, поэтому она немного мазохистская, чтобы утверждать их как плохую практику OO. Хороший совет - не писать абитуриентов без разбора, но я также советую вам не увлекаться ревностью, чтобы искоренить их.
Возьмите это, пуристы.: -)