标题:关于类模板中使用友元input/output操作符
只看楼主
karlzhouzhi
Rank: 1
等 级:新手上路
帖 子:70
专家分:0
注 册:2005-12-25
 问题点数:0 回复次数:8 
关于类模板中使用友元input/output操作符

源程序:
template<int hi,int wid>
class Screen
{
public:
Screen():_cursor(0),_Screen(hi*wid,'#'){}
void home(){_cursor=0;}
void move(int,int);
char get(){return _Screen[_cursor];}
char get(int,int);
bool checkRange(int,int);
void copy(const Screen&);
void set(char c){_Screen=string(hi*wid,c);}
void set(const string&);
void set(const Screen&);

friend ostream& operator<<(ostream &out,const Screen<hi,wid> &s);
friend istream& operator>>(istream &in,Screen<hi,wid> &s);

private:
string _Screen;
int _cursor;
};

template<int hi,int wid>
ostream& operator<<(ostream &out,const Screen<hi,wid> &s)
{
for(int i=1;i<=hi;++i)
{
for(int j=1;j<=wid;++j)
out<<s.get(i,j); //C2663: 'get' : 2 overloads have no legal conversion for 'this' pointer
cout<<endl;
}
cout<<endl;
return out;
}


template<int hi,int wid>
istream& operator>>(istream &in,Screen<hi,wid> &s)
{
s.home();
for(int i=1;i<=hi;++i)
for(int j=1;j<=wid;++j)
in>>s._Screen[s._cursor++]; //友元为什么不能访问私有成员
return in;
}

template<int hi,int wid>
void Screen<hi,wid>::move(int row,int col)
{
if(checkRange(row,col))
{
int r=(row-1)*wid;
_cursor=col-1+r;
}
}


template<int hi,int wid>
bool Screen<hi,wid>::checkRange(int row,int col)
{
if(row<1||row>hi||col<1||col>wid)
{
cerr<<"System coordinate("
<<row<<","<<col
<<") out of bounds.\n";
return false;
}
return true;
}

template<int hi,int wid>
char Screen<hi,wid>::get(int r,int c)
{
move(r,c);
return get();
}

template<int hi,int wid>
void Screen<hi,wid>::copy(const Screen &sobj)
{
if(this!=&sobj)
{
_cursor=sobj._cursor;
_Screen=sobj._Screen;
}
}

template<int hi,int wid>
void Screen<hi,wid>::set(const Screen &s)
{
for(int r=1;r<=hi;++r)
for(int c=1;c<wid;++c)
{
move(r,c);
_Screen[_cursor]=s[_cursor];
}
}

template<int hi,int wid>
void Screen<hi,wid>::set(const string &s)
{
for(int r=1;r<=hi;++r)
for(int c=1;c<=wid;++c)
{
move(r,c);
_Screen[_cursor]=s[_cursor];
}
}

int main(void)
{
Screen<2,3> s1;
cout<<s1;

cout<<"please enter 6(chars):";
cin>>s1;
cout<<s1;


return 0;
}

功能描述:
我定义了一个类模板Screen<hi,wid>,想通过类模板中的friend input&output操作符输出Screen<2,3> s1中的内容
但是,友元的定义有问题:
问题1:error C2663: 'get' : 2 overloads have no legal conversion for 'this' pointer
d:\programe\c++ primer\test3\main.cpp(26) : see reference to function template instantiation 'class std::basic_ostream<char,struct std::char_traits<char> > &__cdecl operator <<(class std::basic_ostream<char,struct std::char_traits<char> > &,
const class Screen<2,3> &)' being compiled
问题2: error C2248: '_Screen' : cannot access private member declared in class 'Screen<2,3>'
d:\programe\c++ primer\test3\screen.h(29) : see declaration of '_Screen'

谢谢:)

搜索更多相关主题的帖子: 用友 操作符 output input 模板 
2006-05-16 15:06
wfpb
Rank: 6Rank: 6
等 级:贵宾
威 望:29
帖 子:2188
专家分:0
注 册:2006-4-2
得分:0 
可能是我孤陋寡闻,第一次见人这样用模板类!
我说说可能的原因吧。
第2个问题,我想是这样的:
int _cursor;是你的类的私有成员;
然而,string类重载的[]运算符是不能调用你自己的类的私有成员的;
这里in>>s._Screen[s._cursor++];应该不是说你的友元函数不能access它,而是string类的[]重载函数不能调用它。或许你把string类设为友员类可以解决这个问题。不知道我说的对不对。

[此贴子已经被作者于2006-5-17 19:41:20编辑过]


[glow=255,red,2]wfpb的部落格[/glow] 学习成为生活的重要组成部分!
2006-05-16 20:06
wfpb
Rank: 6Rank: 6
等 级:贵宾
威 望:29
帖 子:2188
专家分:0
注 册:2006-4-2
得分:0 

请问,这是模板类吗?


[glow=255,red,2]wfpb的部落格[/glow] 学习成为生活的重要组成部分!
2006-05-17 19:57
wfpb
Rank: 6Rank: 6
等 级:贵宾
威 望:29
帖 子:2188
专家分:0
注 册:2006-4-2
得分:0 
怎么没人说句话啊/

[glow=255,red,2]wfpb的部落格[/glow] 学习成为生活的重要组成部分!
2006-05-18 21:50
wfpb
Rank: 6Rank: 6
等 级:贵宾
威 望:29
帖 子:2188
专家分:0
注 册:2006-4-2
得分:0 
aogun:
帮帮忙啊~!
myajax95:
怎么没来说句话啊?
需要朋友们的帮忙

[glow=255,red,2]wfpb的部落格[/glow] 学习成为生活的重要组成部分!
2006-05-19 10:07
aogun
Rank: 5Rank: 5
等 级:贵宾
威 望:17
帖 子:638
专家分:0
注 册:2006-4-5
得分:0 
嘿嘿,我一看这么长的程序就不想看了
这是模板类啊,不过是类模板的部分特化的定义,即某些模板的参数被实际的类型或者值取代了
你说的出错的原因应该是说对点了

世界上总共有 10 种人,一种懂得什么是二进制 ,一种不懂。
2006-05-19 10:17
wfpb
Rank: 6Rank: 6
等 级:贵宾
威 望:29
帖 子:2188
专家分:0
注 册:2006-4-2
得分:0 

但是为什么任意给一个私有数据成员都不能access呢?还有那个get


[glow=255,red,2]wfpb的部落格[/glow] 学习成为生活的重要组成部分!
2006-05-19 10:26
aogun
Rank: 5Rank: 5
等 级:贵宾
威 望:17
帖 子:638
专家分:0
注 册:2006-4-5
得分:0 
我仔细看了一下
get不能用的原因是因为声明了const Screen<hi,wid> &s,如果声明了const,那么就不能访问不是const的成员,把const去掉就行了
cannot access private member declared in class 'Screen<2,3>的错误原因是因为友元函数的声明错误,lz的代码中的声明导致了多对一的情况,所以模板函数当然不能访问模板类中的私有成员,另外,>>全局操作符的重载原型返回类型应该是void,不应该是istream&,所以应该把模板类中对友元>>的声明改为如下声明:
template<int hi,int wid> friend void operator>>(istream &in,Screen<hi,wid> &s);

世界上总共有 10 种人,一种懂得什么是二进制 ,一种不懂。
2006-05-19 11:18
wfpb
Rank: 6Rank: 6
等 级:贵宾
威 望:29
帖 子:2188
专家分:0
注 册:2006-4-2
得分:0 

[glow=255,red,2]wfpb的部落格[/glow] 学习成为生活的重要组成部分!
2006-05-19 12:01



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-64696-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.026291 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved