从c ++中的头文件中定义的友元函数调用函数

时间:2010-10-30 23:55:04

标签: c++ friend-function

我已将>>运算符重新定义为标题中模板类中的友元函数。在其中,我需要调用另一个名为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 个答案:

答案 0 :(得分:1)

友元功能不是会员功能。换句话说,它的范围超出了你的类的范围。通过声明它的朋友,你给它特殊的权限来访问类Forest的受保护成员,但是你必须访问成员方法应该使用该对象的方式。 MememberMethod()语法。

在这种情况下,您需要调用f1.inputHelper(...),而不是直接调用inputHelper(..)。如果你像这样调用inputHelper,我想它应该正常编译。

答案 1 :(得分:0)

在您发布的代码中,您没有声明两个友元函数,而是两个Forest类的方法,因为您已将函数体写入类定义。

你应该让朋友将原型函数放入类中,但在Forest类定义之外重写它们。

答案 2 :(得分: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) */
}