Почему я должен явно объявлять встроенные функции здесь? - PullRequest
0 голосов
/ 01 мая 2011

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

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

Я также знаю, что inline - это просто предложение,и может даже не использоваться компилятором и т. д.

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

Даже если функции были огромными,Я должен был бы объявить их встроенными, и компилятор, возможно, все равно мог бы игнорировать подсказку.

И все же я должен их так или иначе определить.

Пример:

#ifndef texture_math_h__
#define texture_math_h__

float TexcoordToPixel(float coord, float dimension)
{
    return coord * dimension;
}

float PixelToTexcoord(float pixel, float dimension)
{
    return pixel / dimension;
}

float RecalcTexcoord(float coord,float oldDimension, float newDimension)
{
    return PixelToTexcoord(TexcoordToPixel(coord,oldDimension),newDimension);
}
#endif // texture_math_h__

Ошибки, блабла, уже определены в xxx.obj, для каждого модуля, который включает файл

Когда я объявляю все эти строки, он связывается правильно.

В чем причина?Это не огромная проблема, и, черт возьми, оптимизация, вероятно, встроенный материал, найденный в cpp, тоже, верно?

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

Ответы [ 3 ]

4 голосов
/ 01 мая 2011

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

Также обратите внимание, что имена, содержащие двойные подчеркивания, зарезервированы для целей реализации C ++ - вам не разрешено создавать такие имена в вашем собственном коде.

1 голос
/ 01 мая 2011

Это все о одном правиле определения .Это говорит о том, что вы можете иметь только одно определение для каждой не встроенной функции (вместе с различными другими типами сущностей) в программе на C ++ во всех единицах перевода, на которые вы ссылаетесь, чтобы создать программу.

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

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

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

1 голос
/ 01 мая 2011

Функции-члены потенциально встроены - вы не можете принудительно встроить!- если (а) они определены внутри класса или если (б) вы используете встроенное предложение в определении.Обратите внимание, что если вы используете встроенное предложение, вы не должны определять функцию в заголовке - единственным исключением будут шаблоны, так как они являются «специальными».1004 * Каждый пользователь этого заголовка будет иметь определение функций -> несколько определений.Вам нужно разделить определение и декларацию!

...