-3

私はすべてを試しましたが、なぜ機能しないのか理解できません。

g++ スロー:

Queue.H:53: エラー: 「operator<<」 を非関数として宣言

Queue.H:53: エラー: 予期される â;â before â<â トークン

Queue.H:59: エラー: 「プライベート」の前に「」が必要です

コードは次のとおりです。

#ifndef _Queue_H_
#define _Queue_H_
#include <iostream>
#include <string>
using namespace std;

template <class T, int size>

class Queue
{
public:
    Queue():_Num(0){
        T Arr=new T[size];
        for(int i=0;i<size;i++)
            Arr[i]=0;}
    ~Queue(){
        for (int i=0;i<_Num;i++)
            delete Arr_[i];
        delete [] Arr_;
    }
    bool IsEmpty() const{return !_Num ;}
    bool IsFull() const{return (_Num==size);}
    void count() const{return _Num;}
    T& Top() const {
        if(!IsEmpty())
            return Arr_[0];
        else
            throw("empty");
    }
    void operator << (const T & item ) {
        if(!IsFull()){
            Arr_[_Num+1]=item;
            _Num++;}
        else
            throw("full");}
    
    T  operator >> (T & item) {
        if(IsEmpty())
            throw("empty");
        
        item=Arr_[0];
        delete Arr_[0];
        for(int i=1;i<_Num;i++)
            Arr_[i-1]=Arr_[i];
        _Num--;
        return item;}
    
    T operator [] (const T &number){
        return (number<size) ?Arr_[number]:throw("overload");}
    
    friend ostream & operator << <T,size>(ostream & or ,const Queue<T,size> &a){
        for(int i=0;i<a._Num;i++)
            or<<a.Arr_[i];
        return or;
    }
    
private:
    T Arr_[size];
    int _Num;
};
4

2 に答える 2

3

フレンド関数は外部で定義する必要があります。クラスで定義されたフレンド関数にアクセスするなどの問題が発生する可能性があります。クラス内にフレンド宣言を残し、クラス外で関数を定義するだけです。

しかし、テンプレート変数に名前を付ける方法が原因でエラーが発生します。

それ以外の

friend ostream & operator << <T,size>(ostream & or ,const Queue<T,size> &a){

試してみてください

friend ostream & operator << (ostream & or ,const Queue<T,size> &a){

ps _Num-悪い考え

于 2013-01-25T11:15:11.843 に答える
0

私のように密結合を懸念している場合は、特に懸念されますfriend(これは C++ が提供する最も密結合であるため)。そうは言ってoperator<<も、フレンド宣言なしで、クラス内で簡単に実装できるビューがあります。

簡単に言えば、operator<<ostream は単純な print メソッドの美化にすぎません。そして、この美化 (チェーンos << a << b << c...呼び出し) のためだけに、オペレーターは、それが属するべきクラスのメソッドになることができません。非常に多くの人がその演算子のフレンド宣言に頼っていますが、これはカプセル化を破る醜い回避策です。それで、あなたは何ができますか?

template <class T, int size>
class Queue
{
public:
    /**
     * Here comes the method. Inside the class, were it should be, 
     * having all the access it needs. 
     * No template-specialization-friend-declaration needed.
     */
    ostream & printToStream(ostream & or) const 
    { 
        for(int i=0;i<a._Num;i++)
            or<<Arr_[i];
        return or;
    }

private:
    T Arr_[size];
    int _Num;
};

/**
 * Here comes operator<<. It is what it really is:
 * Just a beautification, nothing more, no additional functionality.
 */
template <class T, int size> 
ostream& operator<<(ostream& os, Queue<T,size> const& q)
{ return q.printToStream(os); }

見る?大したことではありません。これを頻繁に行い、メソッドが毎回 printToStream と呼ばれる場合は、それをテンプレートにすることができます。

template <class Printable>
ostream& operator<<(ostream& os, Printable const& p)
{ return p.printToStream(os); }

そして、気をつけたい場合は、そのメンバー function がある場合にのみ、その演算子を enable_if できます。もう "friend operator<< どうすればいいですか?" はもう必要ありません。printToStream を実装するだけで、beautification-operator<< は既に存在します。

于 2013-01-25T13:10:48.123 に答える