Реализация внутри декларации С++

Я хочу включить реализацию функции внутри файла .h.

Я знаю, что я предпочел бы разделить декларацию и реализацию на файлы .h и .c соответственно, это не является частью моего вопроса.

Когда я реализую функцию внутри класса, я не получаю ошибок:

class Foo
{
  public:
    // Class constructor
    Foo() { }
};

Когда я реализую функцию вне класса (все еще в файле .h):

class Foo
{
  public:
    // Class constructor
    Foo();
};

Foo::Foo()
{
}

Я получаю следующую ошибку:  множественное определение Foo:Foo()

Может ли кто-нибудь объяснить мне логику этого? Спасибо.

Ответы

Ответ 1

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

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

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


Подробнее о inline см. http://en.cppreference.com/w/cpp/language/inline. В разделе примеров есть хороший фрагмент кода, который должен помочь.


Вы также можете явно отметить определение вне класса как inline, например @StoryTeller.

Ответ 2

Отметьте его inline

class Foo
{
  public:
    // Class constructor
    inline Foo();
};

inline Foo::Foo()
{
}

Как Любопытный сказал, определение внутри класса неявно встроено. Но если вы определяете его вне класса, в заголовке вы должны явно указать спецификатор.

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