inline — Компиляция функций-членов C ++, определенных вне тела класса

У меня есть файл hpp, как это:

#ifndef __MYLIB_H
#define __MYLIB_H

class A {
public:
void func1();
void func2();
};

void A::func1() {
// maybe do something
}

#endif

Существует соответствующий файл cpp, в котором есть реализация func2. Заголовочный файл включен в другие файлы проекта (и они включены в еще большее количество файлов). Когда я пытаюсь построить это, я получаю ошибки компоновщика «множественного определения» для func1, Почему это должно произойти? Так как я защитил заголовочный файл с помощью #ifndefЯ не ожидал ошибки.

Если я добавлю ключевое слово inline к определению func1, то все в порядке. Так что, если мне не важно, будет ли функция встроенной, и я не хочу иметь определение в теле класса, я не могу включить определение в файл hpp? Если кто-то может объяснить, что здесь происходит, это будет очень полезно. Я использую GCC 6.

1

Решение

Напомним, что содержимое всего заголовка, а также любые файлы, которые он может включать, практически «вставляются» в каждый блок перевода* это включает в себя заголовок в точке включения.

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

Проблема решается объявлением функции inlineпотому что C ++ допускает несколько определений встроенных функций, если они идентичны друг другу. Перемещение тела функции в объявление класса также работает, потому что такие функции автоматически рассматриваются inline,

* В этом контексте «единица перевода» — это причудливое имя для вашего файла CPP.

2

Другие решения

Проблема в том, что вы переопределяете func1 в каждом файле.

#include Директива — это очень простая команда, которая просто вставляет содержимое файла заголовка в указанное место.

Результатом этого является то, что каждый раз, когда вы #include ваш заголовок вы «переопределяете» func1 в этом файле.

2

Реализации обычно идут в связанных .cpp файлы. Поместить их в заголовки проблематично. inline это хак, чтобы обойти это, вы, вероятно, не хотите использовать, так как он удаляет этот код везде, где он появляется, что приводит к дикому дублированию.

Помните, #include очень похоже на вставку этого файла в код там, где появляется эта директива. Неверно иметь более одной реализации для функции, поэтому они разделены между заголовком для целей подписи, поэтому понятно, как правильно использовать эти функции, и реализацией для реального кода.

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector