С++ для начинающих




Несколько слов о заголовочных файлах - часть 3


// ошибка: не должно быть в заголовочном файле

const char* msg = "?? oops: error: ";

Проблема вызвана тем, что msg не константа. Это неконстантный указатель, адресующий константу. Правильное объявление выглядит так (полное описание объявлений указателей см. в главе 3):

const char *const  msg = "?? oops: error: ";

Такое определение может появиться в разных файлах.

Схожая ситуация наблюдается и со встроенными функциями. Для того чтобы компилятор мог подставить тело функции “по месту”, он должен видеть ее определение. (Встроенные функции были представлены в разделе 7.6.)

Следовательно, встроенная функция, необходимая в нескольких исходных файлах, должна быть определена в заголовочном файле. Однако спецификация inline – только “совет” компилятору. Будет ли функция встроенной везде или только в данном конкретном месте, зависит от множества обстоятельств. Если компилятор пренебрегает спецификацией inline, он генерирует определение функции в исполняемом файле. Если такое определение появится в данном файле больше одного раза, это будет означать ненужную трату памяти.

Большинство компиляторов выдают предупреждение в любом из следующих случаев (обычно это требует включения режима выдачи предупреждений):

  • само определение функции не позволяет встроить ее. Например, она слишком сложна. В таком случае попробуйте переписать функцию или уберите спецификацию inline и поместите определение функции в исходный файл;
  • конкретный вызов функции может не быть “подставлен по месту”. Например, в оригинальной реализации С++ компании AT&T (cfront) такая подстановка невозможна для второго вызова в пределах одного и того же выражения. В такой ситуации выражение следует переписать, разделив вызовы встроенных функций.
  • Перед тем как употребить спецификацию inline, изучите поведение функции во время выполнения. Убедитесь, что ее действительно можно встроить. Мы не рекомендуем объявлять функции встроенными и помещать их определения в заголовочный файл, если они не могут быть таковыми по своей природе.

    Упражнение 8.3

    Установите, какие из приведенных ниже инструкций являются объявлениями, а какие – определениями, и почему:

    (a) extern int ix = 1024;

    (b) int iy;

    (c) extern void reset( void *p ) { /* ... */ }

    (d) extern const int *pi;

    (e) void print( const matrix & );

    Упражнение 8.4

    Какие из приведенных ниже объявлений и определений вы поместили бы в заголовочный файл? В исходный файл? Почему?

    (a) int var;

    (b) inline bool is_equal( const SmallInt &, const SmallInt & ){ }

    (c) void putValues( int *arr, int size );

    (d) const double pi = 3.1416;

    (e) extern int total = 255;




    Содержание  Назад  Вперед