вызов функции из функции-друга, определенной в заголовке в c ++ - PullRequest
1 голос
/ 31 октября 2010

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

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

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 выходит за рамки класса, но я не уверен, как решить эту проблему.

Ответы [ 3 ]

1 голос
/ 31 октября 2010

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

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

0 голосов
/ 31 октября 2010

Вы путаете два понятия здесь: функция друга и функция члена.Функция друга определяется вне определения класса.Внутри класса находится только объявление 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) */
}
0 голосов
/ 31 октября 2010

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...