Если мы определяем функцию-член внутри самого определения класса, она обязательно обрабатывается встроенным или это просто запрос компилятору, который он может игнорировать.
Ответ 2
Как указано другими, метод, определенный внутри класса, автоматически запрашивается в строке.
Полезно понять, почему.
Предположим, что это не так. Вам нужно будет генерировать код для такой функции, и везде, где он вызывается, команда перехода к подпрограмме должна ссылаться на местоположение через компоновщик.
class A {
public:
void f() { ... your code ... }
};
Каждый раз, когда этот код отображается, если он не встроен, компилятор может только предположить, что он должен быть сгенерирован, поэтому он будет генерировать символ. Предположим, что это было так:
A__f_v:
Если этот символ был глобальным, то, если вы случайно включили этот код класса несколько раз в разные модули, у вас будет многократно определенная ошибка символа во время соединения. Поэтому он не может быть глобальным. Вместо этого он локальный файл.
Представьте, что вы включили вышеупомянутый заголовочный файл в несколько модулей. В каждом из них он собирается создать локальную копию этого кода. Что лучше, чем не компиляция вообще, но вы получаете несколько копий кода, когда вам действительно нужно только одно.
Это приводит к следующему выводу: если ваш компилятор не будет встроен в функцию, вам значительно лучше объявить его где-то один раз, а не запрашивать его встраивание.
К сожалению, то, что есть и не является встроенным, не переносимо. Он определяется автором компилятора. Хорошее эмпирическое правило состоит в том, чтобы всегда делать каждый лайнер, особенно все функции, которые сами называют функцией, встроенными, при удалении служебных данных. Все, что ниже трех строк линейного кода, почти наверняка хорошо. Но если у вас есть цикл в коде, вопрос заключается в том, позволит ли компилятор его встроить, и более того, какую выгоду вы бы увидели, даже если он сделал то, что вы хотите.
рассмотрите этот встроенный код:
inline int add(int a, int b) { return a + b; }
Он не только почти такой же, как прототип, будет в исходном коде, но язык сборки, сгенерированный встроенным кодом, будет меньше, чем вызов обычной. Таким образом, этот код меньше и быстрее.
И, если вы случайно проходите в константах:
int c= add(5,4);
Он разрешен во время компиляции, и нет кода.
В gcc, я недавно заметил, что даже если я не встроенный код, если он локальный для файла, они будут скрытно встраивать его в любом случае. Это только в том случае, если я объявляю функцию в отдельном исходном модуле, что они не оптимизируют вызов.
На другом конце спектра предположим, что вы запрашиваете строку в 1000 строк кода. Даже если ваш компилятор достаточно глуп, чтобы согласиться с ним, единственное, что вы сохраняете, - это сам вызов, и стоимость заключается в том, что каждый раз, когда вы его вызываете, компилятор должен вставить весь этот код. Если вы вызываете этот код n раз, ваш код увеличивается на размер подпрограммы * n. Таким образом, ничего большего, чем 10 строк, в значительной степени не стоит встраивать, за исключением особого случая, когда его называют только очень маленьким числом раз. Примером этого может быть частный метод, вызываемый только двумя другими.
Если вы запрашиваете встроенный метод, содержащий цикл, это имеет смысл только в том случае, если он часто выполняется несколько раз. Но рассмотрим цикл, который повторяется миллион раз. Даже если код встроен, процент времени, проведенного в вызове, крошечный. Поэтому, если у вас есть методы с циклами в нем, которые, как правило, все равно больше, их стоит удалить из файла заголовка, потому что они: a) будут отклоняться как встроенные компилятором и б), даже если они были встроены, обычно не собираюсь предоставлять какую-либо выгоду