функция в C ++: определите ее перед использованием - PullRequest
3 голосов
/ 03 марта 2012

В C / C ++ функция вызывающего может вызывать функцию вызываемого в том и только в том случае, если функция вызываемого абонента является видимой для вызывающего, что означает, что определение вызываемого должно быть выполнено до того, как оно будет использовано, в противном случае используйте forward-объявление.*

Вот моя проблема,

class A
{
    public:
        void foo()
        {
            bar();
        }

        void bar()
        {
            //...
        }
};

int main()
{
    A a;
    a.foo();
}

Приведенный выше код будет работать нормально.Но foo вызывает bar, и я не поставил определение bar перед foo или не объявил форвард bar, как может работать вызов на bar в foo?Как мог компилятор найти bar?

Ответы [ 4 ]

5 голосов
/ 03 марта 2012

Язык говорит, что областью объявления функции-члена является весь класс (свободно), так что это нормально.

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

Таким образом, он смотрит только на вызов bar в конце класса, к которому времени он имеетвидел его декларацию и все хорошо.

3 голосов
/ 03 марта 2012

На самом деле, это называется Forward reference

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

Разрешение прямых ссылок может значительно увеличить сложность и требования к памяти компилятора и, как правило, препятствует реализации компилятора за один проход.

3 голосов
/ 03 марта 2012

Тело функции-члена, определенное внутри определения класса, является особым случаем: для поиска имени это выглядит так, как если бы функция-член была определена сразу после окончания определения класса.

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

1 голос
/ 03 марта 2012

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

...