2010-10-30 2 views
1

Я переопределил оператор >> как функцию друга в классе шаблона в заголовке. В нем мне нужно вызвать другую функцию с именем inputHelper, которую я также определил в заголовке. (Входной помощник рекурсивный)вызов функции из функции друга, определенной в заголовке в C++

файла заголовок выглядит следующим образом:

template< typename NODETYPE > class Forest 
{ 
    /* (other friends) */ 
    friend void inputHelper(istream& file, int previousDepth, 
     ForestNode<NODETYPE>& previousNode, ForestNode<NODETYPE> *nodeArray, 
     int nodeCount) 
    { 
     /* (dostuff) */ 
     if(someconditional) 
     { 
      /* call inputHelper */ 
     } 
    } 

    friend istream& operator>>(istream& file, Forest<NODETYPE>& f1) 
    { 
     /* (dostuff) */ 
     /* (call inputHelper) */ 
    } 
public: 
    /* ... */ 
private: 
    /* ... */ 
} 

Однако, при компиляции, он говорит |140|error: 'inputHelper' was not declared in this scope|. Вам нужно сделать что-то особенное, потому что оба они определены как функции друзей в заголовке? Я понимаю, что inputHelper находится вне сферы действия класса, но я не уверен, как это решить.

+0

Пожалуйста, пост код, который воспроизводит проблему (псевдо-код, который вы, вероятно, не отвечал бы составить по ряду причин, не связанных с вашей проблемы) и сказать, где использование именно вы получите сообщение об ошибке ... – sth

ответ

1

Функция друга не является функцией-членом. Другими словами, это область выходит за рамки вашего класса. Объявляя ее другом, вы предоставляете ей особые привилегии для доступа к защищенным членам класса Forest, но способ, которым вы должны обращаться к методам-членам, должен использовать этот объект. Синтаксис MememberMethod().

В этом случае вам нужно вызвать f1.inputHelper (...), а не напрямую вызвать inputHelper (..). Если вы вызове inputHelper, как это, я думаю, он должен компилироваться нормально.

0

В коде, который вы опубликовали, вы не объявляете две функции друга, а два метода класса Forest, поскольку вы написали тело функции в определение класса.

Вы должны позволить прототипам друзей использовать класс, но переписать их за пределами определения класса леса.

0

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

Включая в себя корпус inputHelper() и operator>> вместе с их объявлениями friend, вы сделали это неоднозначным, являются ли они функциями-членами или друзьями. Более того, поскольку эти функции полностью определены внутри класса, они не существуют вне класса, поэтому компилятор дает вам ошибку при попытке их использования.

На самом деле это еще более интересно. Вы уходите с operator>>, являясь функцией-членом, потому что синтаксис для ее использования тот же, независимо от того, является ли он членом или нет. Однако, когда вы вызываете inputHelper(), как если бы он был нечленом, компилятор дает вам ошибку.

Способ исправить это, чтобы дать понять компилятору, который является другом и членом. Если вы хотите, чтобы operator>> и inputHelper() были друзьями, вы должны оставить объявления друзей внутри класса и поместить их определения, т.е. е. их тела вне класса.


template class Forest 
{ 
    /* (other friends) */ 

    friend void inputHelper(istream& file, int previousDepth, 
     ForestNode& previousNode, ForestNode *nodeArray, 
     int nodeCount); 

    friend istream& operator>>(istream& file, Forest& f1); 
public: 
    /* ... */ 
private: 
    /* ... */ 
}; 

void inputHelper(istream& file, int previousDepth, 
     ForestNode& previousNode, ForestNode *nodeArray, 
     int nodeCount) 
{ 
     /* (dostuff) */ 
     if(someconditional) 
     { 
      /* call inputHelper */ 
     } 
} 

istream& operator>>(istream& file, Forest& f1) 
{ 
     /* (dostuff) */ 
     /* (call inputHelper) */ 
} 
Смежные вопросы