宣布âoperator<<â为非功能性

时间:2013-01-25 11:12:20

标签: c++ operator-overloading friend-function

我已经尝试了一切,我无法理解为什么它不起作用。

  

g ++ throw:

     

Queue.H:53:错误:声明âoperator<<â作为非功能

     

Queue.H:53:错误:预期â€â€â€â€œ令牌

     

Queue.H:59:错误:预期â;âprivate之前

代码是:

#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;
};

2 个答案:

答案 0 :(得分:3)

朋友功能应该在外面定义,你可以点击Access friend function defined in class之类的问题。你应该在类中留下一个朋友声明,并在课外定义函数。

但是您的错误是由于您为模板变量命名的方式。

而不是

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

尝试

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

P.S。 _Num - Bad Idea

答案 1 :(得分:0)

如果你担心像我这样的紧耦合,你会特别关注friend(因为这是C ++必须提供的最紧密耦合)。也就是说,有operator<<的视图使得在课堂上实现变得容易,没有任何朋友声明:

简而言之,{ostream的operator<<仅仅是对简单打印方法的美化。并且只是因为这种美化(链接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); }

如果你想获得幻想,你可以启用运算符only if it has that member function。不再需要“朋友操作员&lt;&lt;我应该再怎么做?”,只需实现printToStream,并且美化操作符&lt;&lt;已经存在。