1

我已将>>运算符重新定义为标题中模板类中的友元函数。在其中,我需要调用另一个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超出了课程的范围,但我不确定如何解决这个问题。

4

3 回答 3

1

友元函数不是成员函数。换句话说,它的作用域超出了你的类的作用域。通过声明它为友元,你赋予它访问 Forest 类的受保护成员的特殊权限,但是你必须访问的成员方法应该使用对象的方式。 MememberMethod() 语法。

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

于 2010-10-31T00:32:35.920 回答
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) */
}
于 2010-10-31T12:16:01.540 回答
0

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

您应该让友元函数原型进入类,但在 Forest 类定义之外重写它们。

于 2010-10-31T00:36:07.010 回答