在做C++Primer 4th的p555习题16.39的时候,终于意识到友元声明的依赖性(P553)
最终写出来的源代码如下所示,可以看到这很多的声明:
#include
<
iostream
>
using namespace std;
template < int tHeight, int tWidth >
class Screen;
// 声明友元函数的原型,因此能够在类Screen里面声明它的限定版本,由于这俩个声明用到了Screen,导致了上两行的Screen类的声明
template < int tHeight, int tWidth >
ostream & operator << (ostream & , const Screen < tHeight, tWidth >& );
template < int tHeight, int tWidth >
istream & operator >> (istream & , Screen < tHeight, tWidth >& );
// 以下是Screen类的定义,用了两个非类类型模板形参
template < int tHeight, int tWidth >
class Screen{
public :
Screen():height(tHeight), width(tWidth){}
// 以下是具体的友元声明,很明显,这里要对函数名进行限定
friend ostream &
operator << < tHeight, tWidth > (ostream & , const Screen < tHeight, tWidth >& );
friend istream &
operator >> < tHeight, tWidth > (istream & , Screen < tHeight, tWidth >& );
private :
int height;
int width;
};
// 两个友元函数的定义
template < int tHeight, int tWidth > // 其实这一行已经是模板的形参的声明列表,在这之后,这两个名字就可以作为实参来使用了
ostream & operator << (ostream & os, const Screen < tHeight, tWidth >& sc){
os << " Screen: " << sc.width << " , " << sc.height << endl;
return os;
}
template < int tHeight, int tWidth > // 其实这一行已经是模板的形参的声明列表,在这之后,这两个名字就可以作为实参来使用了
istream & operator >> (istream & is , Screen < tHeight, tWidth >& sc){
is >> sc.height >> sc.width;
return is ;
}
int main(){
// 使用过程,相当简洁
Screen < 3 , 5 > sc;
cout << sc << endl;
cout << " 请输入Screen: " ;
cin >> sc;
cout << sc << endl;
system( " pause " );
return 0 ;
}
using namespace std;
template < int tHeight, int tWidth >
class Screen;
// 声明友元函数的原型,因此能够在类Screen里面声明它的限定版本,由于这俩个声明用到了Screen,导致了上两行的Screen类的声明
template < int tHeight, int tWidth >
ostream & operator << (ostream & , const Screen < tHeight, tWidth >& );
template < int tHeight, int tWidth >
istream & operator >> (istream & , Screen < tHeight, tWidth >& );
// 以下是Screen类的定义,用了两个非类类型模板形参
template < int tHeight, int tWidth >
class Screen{
public :
Screen():height(tHeight), width(tWidth){}
// 以下是具体的友元声明,很明显,这里要对函数名进行限定
friend ostream &
operator << < tHeight, tWidth > (ostream & , const Screen < tHeight, tWidth >& );
friend istream &
operator >> < tHeight, tWidth > (istream & , Screen < tHeight, tWidth >& );
private :
int height;
int width;
};
// 两个友元函数的定义
template < int tHeight, int tWidth > // 其实这一行已经是模板的形参的声明列表,在这之后,这两个名字就可以作为实参来使用了
ostream & operator << (ostream & os, const Screen < tHeight, tWidth >& sc){
os << " Screen: " << sc.width << " , " << sc.height << endl;
return os;
}
template < int tHeight, int tWidth > // 其实这一行已经是模板的形参的声明列表,在这之后,这两个名字就可以作为实参来使用了
istream & operator >> (istream & is , Screen < tHeight, tWidth >& sc){
is >> sc.height >> sc.width;
return is ;
}
int main(){
// 使用过程,相当简洁
Screen < 3 , 5 > sc;
cout << sc << endl;
cout << " 请输入Screen: " ;
cin >> sc;
cout << sc << endl;
system( " pause " );
return 0 ;
}
注意类外面的函数原型声明预定义,和类里面的函数声明是不完全一样的。