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() 構文。

この場合、inputHelper(..) を直接呼び出すのではなく、f1.inputHelper(...) を呼び出す必要があります。このようにinputHelperを呼び出すと、正常にコンパイルされるはずだと思います。

于 2010-10-31T00:32:35.920 に答える
0

ここでは、フレンド関数とメンバー関数という 2 つの概念を混同しています。フレンド関数がクラス定義の外で定義されています。クラス内にあるのはfriend宣言だけで、他の場所で定義されたそのような非メンバー関数がクラスのプライベート メンバーにアクセスできることを単に示しています。

inputHelper()andの本体を宣言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

投稿したコードでは、関数本体をクラス定義に記述したため、2 つのフレンド関数を宣言していませんが、Forest クラスの 2 つのメソッドを宣言しています。

フレンド関数のプロトタイプをクラスに入れる必要がありますが、Forest クラス定義の外でそれらを書き直してください。

于 2010-10-31T00:36:07.010 に答える