Почему определение метода не является обязательным?

0

Я не уверен, как работает этот код. По моему пониманию должен быть определен весь объявленный метод.

class Test
{
public:
void foo();
};

int main()
{
Test t;
return 0;
}

В классе Test метод foo() объявлен, но не определен, но этот код работает нормально. Пожалуйста, объясните, почему это работает. Разве это неправильно делать, потому что только объявленный метод бесполезен, если он не является абстрактным классом или интерфейсом? Мое предположение - объявление метода говорит компилятору об этом, поэтому компилятор не жалуется на это, и он будет работать нормально, пока кто-то не попытается использовать этот метод. Если это так, все равно не имеет смысла, почему это разрешено? Есть ли какая-то конкретная причина или использование этого?

  • 1
    какой код вы запускаете в Java?
  • 0
    В C ++, потому что вы не вызываете Test::foo() . Попробуйте t.foo() в main .
Показать ещё 4 комментария
Теги:
methods

2 ответа

1
Лучший ответ

Он "работает", потому что ничего не вызывает функция Test::foo.

Компилятор не имеет возможности узнать, должен ли Test быть определен в текущем блоке компиляции [1], или есть test.cpp который реализует функцию Test::foo. Следовательно, компилятор должен признать, что вы здесь не определяете функцию.

В случае, когда у вас есть два файла: один с main и один, содержащий Test::foo, это объединяется на более позднем этапе компоновки компиляции, когда компилятор принимает все различные компоненты, из которых состоит ваше программное обеспечение и помещает их вместе. Это может быть "в будущем" в вашем процессе обучения, но именно по этой причине компилятор не жалуется на это "сейчас". И поскольку вы на самом деле не пытаетесь использовать функцию Test::foo, "для этого нет необходимости", поэтому ошибки не возникает.

[1] Обратите внимание, что это действительно не имеет значения для реального компилятора, если у вас есть class Test в главном файле или он был включен из test.h, так как часть #include рассматривается до того, как компилятор действительно пытается "понять" " код.

Edit: Можно, конечно, рассуждать здесь, что этот код вздор. В чем смысл объявления функции, которая не используется. Но это не значит, что компилятор/компоновщик должен решить. Если вы не используете что-то, вам не нужно его определять. Это правила.

  • 0
    спасибо @mats, так что именно компоновщик на самом деле заботится о связывании вызова метода с его телом, а не с компилятором. верный ?
  • 0
    Да, компоновщик будет «разрешать» вызовы функций из одного модуля компиляции (исходного файла) в другой. До этого момента компилятору нужно только объявление, чтобы определить, что функция «существует». И компоновщик решает только то, что действительно нужно. Поэтому, если вы объявляете функцию и никогда не вызываете ее, она не будет нужна компоновщику. Это на самом деле важно: если вы вызываете функцию в библиотеке, которая объявляется вместе с целой кучей других функций, вы НЕ ДЕЙСТВИТЕЛЬНО хотите, чтобы все эти функции также были перетащены, если они не нужны.
5

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню