2012-03-03 2 views
3

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

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

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

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

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

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

ответ

5

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

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

Поэтому он смотрит только на вызов bar в конце класса, после чего он увидел его объявление, и все хорошо.

+0

Если я переведу определение функции из тела класса, то объявление функции в классе тела будет действовать как forward-decl, правильно? – Alcott

+0

Да. И если вы переместите их оба, вы можете определить их в любом порядке. –

3

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

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

3

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

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

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

+0

В соответствии с вашим ответом я читал, что 'forward-reference' устарел на C++? – Alcott

+0

** forward reference ** - новая функция 'C++' по сравнению с 'C'. – kev

1

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

+1

Вы по-прежнему сталкиваетесь с проблемой, если попытаетесь использовать тип, являющийся членом класса, до его определения. –