Метод, объявленный в классе, но не определенный

У меня есть класс, который объявляет метод, но не реализует его. Этот метод не является виртуальной функцией. В соответствующем файле cpp я не нашел определения того же метода. Были определены все другие методы, объявленные в классе.

Я скомпилировал код, и все прошло отлично. У меня создалось впечатление, что cpp должен определять определение объявленного метода.

Цените, если кто-то может разработать то же самое. Я использую компилятор cl из VS2010.

Ответ 1

Ваш код будет компилироваться, но он даст ошибки привязки.

Построение исполняемого файла вашего проекта включает в себя два этапа:

  • Подборка
  • Связь

В Компиляция компилятор просто переводит исходный код в код объекта, проверяя семантику языка. Во время Связывания компоновщик фактически ищет определения символов и создает исполняемый файл из нескольких объектных файлов (созданных во время компиляции).

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

Обратите внимание, что компоновщику необходимо связать только те символы, которые используются вашей программой,
Например: если ваша программа объявляет функцию, не предоставляет определения, а затем никогда не использует/не вызывает функцию в любом месте, компоновщику не нужно вставлять код для перехода на адрес, где объектный код для функции находится на любом месте вызова функции.
Учитывая такой сценарий, компоновщику просто не нужно вообще искать определение функции. Следовательно, код будет компилироваться и связываться.

Ответ 2

Нет необходимости в том, чтобы этот метод был реализован в конкретном файле. Действительно, (или была) считается хорошей практикой программирования, чтобы иметь один файл для каждого метода, чтобы уменьшить раздувание при связывании с библиотеками.

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

Ответ 3

Это обычная техника для предотвращения назначения или копирования. Если вы объявите его, но не определите его, произойдет ошибка связывания, если вы попытаетесь его использовать, то есть предотвратите непреднамеренное использование пользователями

Ответ 4

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