Я не уверен, как работает этот код. По моему пониманию должен быть определен весь объявленный метод.
class Test
{
public:
void foo();
};
int main()
{
Test t;
return 0;
}
В классе Test
метод foo()
объявлен, но не определен, но этот код работает нормально. Пожалуйста, объясните, почему это работает. Разве это неправильно делать, потому что только объявленный метод бесполезен, если он не является абстрактным классом или интерфейсом? Мое предположение - объявление метода говорит компилятору об этом, поэтому компилятор не жалуется на это, и он будет работать нормально, пока кто-то не попытается использовать этот метод. Если это так, все равно не имеет смысла, почему это разрешено? Есть ли какая-то конкретная причина или использование этого?
Он "работает", потому что ничего не вызывает функция Test::foo
.
Компилятор не имеет возможности узнать, должен ли Test
быть определен в текущем блоке компиляции [1], или есть test.cpp
который реализует функцию Test::foo
. Следовательно, компилятор должен признать, что вы здесь не определяете функцию.
В случае, когда у вас есть два файла: один с main
и один, содержащий Test::foo
, это объединяется на более позднем этапе компоновки компиляции, когда компилятор принимает все различные компоненты, из которых состоит ваше программное обеспечение и помещает их вместе. Это может быть "в будущем" в вашем процессе обучения, но именно по этой причине компилятор не жалуется на это "сейчас". И поскольку вы на самом деле не пытаетесь использовать функцию Test::foo
, "для этого нет необходимости", поэтому ошибки не возникает.
[1] Обратите внимание, что это действительно не имеет значения для реального компилятора, если у вас есть class Test
в главном файле или он был включен из test.h
, так как часть #include
рассматривается до того, как компилятор действительно пытается "понять" " код.
Edit: Можно, конечно, рассуждать здесь, что этот код вздор. В чем смысл объявления функции, которая не используется. Но это не значит, что компилятор/компоновщик должен решить. Если вы не используете что-то, вам не нужно его определять. Это правила.
Компилятор не жалуется на такой код, потому что он не может - вы могли бы написать определение функции в каком-то другом файле. Только компоновщик может сказать вам, что во всех ваших файлах нет определения функции. Но поскольку вы вообще не использовали эту функцию, ссылка на эту функцию отсутствует, компоновщик тоже не жалуется.
Test::foo()
. Попробуйтеt.foo()
вmain
.