Почему функции-члены класса, определенные вне класса (но в заголовочном файле), должны быть встроены? - PullRequest
0 голосов
/ 02 июня 2018

Я прочитал существующие ответы в двух значениях inline, но я все еще в замешательстве.

Предположим, у нас есть следующий заголовочный файл:

// myclass.h

#ifndef INCLUDED_MYCLASS
#define INCLUDED_MYCLASS

class MyClass
{
   public:
      void foo(); // declaration
};

inline void MyClass::foo()
{
    // definition
}

#endif

Почему void foo(), который определен вне класса в файле, должен быть явно определен с inline?

Ответы [ 2 ]

0 голосов
/ 02 июня 2018

Если вы поместите MyClass::foo() в заголовочный файл и не сможете объявить его inline, то компилятор сгенерирует тело функции для каждого модуля компиляции, который #include содержит заголовок, и они будут конфликтовать во время компоновки.Обычная ошибка, выдаваемая компоновщиком, - что-то вроде Multiple definition of symbol MyClass::foo() или что-то подобное.Объявление функции inline позволяет избежать этого, и компилятор и компоновщик должны быть в сговоре по этому поводу.

Как вы упоминаете в своем комментарии, ключевое слово inline также действует как подсказка компилятору, который вы бы хотели, чтобы функция была фактически встроенной, потому что (предположительно) вы часто вызываете ее и больше заботитесь о скорости, чем о размере кода.Хотя компилятору не требуется выполнять этот запрос, поэтому он может генерировать одно или несколько тел функций (в разных единицах компиляции), поэтому компоновщик должен знать, что они на самом деле все одинаковы, и что ему нужно только сохранить один изих (любой сделает).Если бы он не знал, что все они одинаковы, он бы не знал, что делать, поэтому «классическим» поведением всегда было появление ошибки.

Учитывая, что компиляторы в наши дни частов любом случае встроенные небольшие функции, большинство компиляторов также имеют какое-то ключевое слово noinline, но это не является частью стандарта.

Подробнее о inline в cppreference .

0 голосов
/ 02 июня 2018

Это потому, что вы определили MyClass::foo в заголовочном файле.Или, если быть более абстрактным, это определение будет присутствовать в нескольких единицах перевода (каждый файл .cpp, содержащий заголовок).

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

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

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

InНа практике это означает, что компоновщик будет просто использовать первое определение MyClass::foo и использовать его везде, игнорируя остальные:


1 : если это не такваша программа некорректна и не требует никакой диагностики.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...