Как эти две функции, определенные в одном классе, могут переадресовывать друг другу без прямого объявления?

В то время я изучаю код с boost/asio. Многие примеры кода используют комбинацию async_accept и bind. В коде сервера я сталкиваюсь с чем-то вроде этого:

class Tcp_server
{
public:
    Tcp_server()
    {

    }
    void start_accept(int a)
    {
        if(a>0)
        {
            cout<<a<<endl;
            handle_accept(a-1);
        }

    }

    void handle_accept(int a)
    {
        if(a>0)
        {
            cout<<a<<endl;
            start_accept(a-1);
        }

    }
};

Если я создаю экземпляр Tcp_server и вызываю либо handle_accept, либо start accept, он работает. Но если я опустил инкапсуляцию класса Tcp_server, компилятор будет жаловаться, что "handle_accept не объявлен". Я просто задаюсь вопросом, автоматически ли компилятор будет объявлять все функции, определенные в одном классе. Может ли кто-нибудь объяснить, почему?

Ответ 1

Функции, определенные в определении класса, имеют точно такую ​​же семантику, как если бы они были объявлены только в определении класса и затем определены сразу после определения класса. Единственное отличие состоит в том, что такие функции-члены неявно объявляются встроенными, в то время как определение функции либо не является встроенным, либо явно встроенным. То есть с точки зрения компилятора функции объявляются и класс определяется до определения функций.

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