本站首页    管理页面    写新日志    退出


[c++读书笔记]friend的注意事项
sunshine 发表于 2006/10/27 19:36:20

  1、整个类可以是另一个类的友元,该友元也可以称做为友类。 class Internet;  class Country  { friend class Internet;//友类的声明,形象的说:Internet是Country的朋友 }; 这样Internet类中的成员函数可以通过函数参数(也就是Country对象或者Country对象引用)访问Country类的私有成员。 在迭代器中也有类似的用法:(实质上这个是嵌套友元类的用法,同时这也是一种设计模式) Template<class T, int ssize = 100> Class StackTemplate {      T stack[ssize];//private      Int top;      StackTemplate():top(0){} //constructor        Class iterator;//forward declaration      Friend class iterator; //让iterator类成为StackTemplate的友元类      Class iterator //定义一个类      {          StackTemplate& s;          Int index          iterator (StackTemplate& st): s(st),index(0){}          iterator (StackTemplate& st, bool):s(st),index(s.top){}          T operator*() const { return s.stack[index];} //这里operator*()访问了StackTemplate类是私有成员          //重载++,+ 等运算符 } iterator begin() { return iterator(*this) } iterator end() { return  iterator(*this, bool) } } 使用: StackTemplate<int> is; StackTemplate<int>::iterator iterStart = is.begin(); StackTemplate<int>::iterator iterEnd = is.end();   2、一个类的成员函数可以是另一个类的友元 class Internet;  class Country  {  void Editurl(Internet &temp);//成员函数的声明  }; class Internet  {  friend void Country::Editurl(Internet &temp);//友元函数的声明  }; 通过友元函数的参数Internet对象,访问Internet类的私有成员。   3、一个普通函数可以是(多个)类的友元函数。这类普通函数的参数都有类的对象,从而通过该对象,操作该类的私有成员,该函数被当作全局函数。   4、二元中缀运算符,如果第一个运算数不是类对象,通常把该函数声明为该类的友元函数。另外:在ostream的重载<<或者>>符号的时候,通常声明为友元函数。   5、友元关系既不继承,也不传递 我不见得信任我朋友的孩子。友元的特权不被继承。友元的派生类不一定是友元。如果 Fred 类声明Base类是友元,那么Base类的派生类不会自动地被赋予对于Fred的对象的访问特权。 我不见得信任我朋友的朋友。友元的特权不被传递。友元的友元不一定是友元。如果Fred类声明Wilma类是友元,并且Wilma类声明Betty类是友元,那么Betty类不会自动地被赋予对于Fred的对象的访问特权。 你不见得仅仅因为我声称你是我的朋友就信任我。友元的特权不是自反的。如果Fred类声明Wilma类是友元,则Wilma对象拥有访问Fred对象的特权,但Fred对象不会自动地拥有对Wilma对象的访问特权。 6、友元函数主要缺点是需要额外的代码来支持动态绑定。 要得到虚友元(virtual friend)的效果,友元函数应该调用一个隐藏的(通常是 protected:)虚成员函数。  class Base { public:   friend void f(Base& b);   // ... protected:   virtual void do_f();   // ... };  inline void f(Base& b) {   b.do_f(); }  class Derived : public Base { public:   // ... protected:   virtual void do_f();  // "覆盖" f(Base& b)的行为   // ... };  void userCode(Base& b) {   f(b); } 在userCode(Base&)中的f(b)语句将调用虚拟的  b.do_f()。这意味着如果b实际是一个派生类的对象,那么Derived::do_f()将获得控制权。注意派生类覆盖的是保护的虚(protected: virtual)成员函数 do_f(); 而不是它友元函数f(Base&)。 一个使用虚友元函数用法更实际的例子:(为一个完整的继承层次的类提供打印)  class Base { public:   friend std::ostream& operator<< (std::ostream& o, const Base& b);   // ... protected:   virtual void printOn(std::ostream& o) const; };  inline std::ostream& operator<< (std::ostream& o, const Base& b) {   b.printOn(o);   return o; }  class Derived : public Base { protected:   virtual void printOn(std::ostream& o) const; }; 另见:http://tech.163.com/05/0405/14/1GJ664RL00091589.html

阅读全文(3937) | 回复(1) | 编辑 | 精华

回复:friend的注意事项
vanroque发表评论于2006/10/28 19:42:39

C++太难学了,学不会阿,还是java好学

个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除

回复:friend的注意事项
Jeffern(游客)发表评论于2006/10/28 15:44:46

最近在业务上很用功!
个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
» 1 »

发表评论:
昵称:
密码:
主页:
标题:
验证码:  (不区分大小写,请仔细填写,输错需重写评论内容!)

 
«October 2025»
1234
567891011
12131415161718
19202122232425
262728293031

  公告

有一种鸟儿是永远关不住的
因为它的每片羽翼上都沾满了自由的光辉

方向:计算机视觉 人工智能 演化算法

 


  我的分类(专题)
  最近日志

  最新评论

  留言板

  链接

  Blog信息
blog名称:阳光海岸心
日志总数:166
评论数量:237
留言数量:-4
访问次数:1459164
建立时间:2006年6月2日



站点首页 | 联系我们 | 博客注册 | 博客登陆

Sponsored By W3CHINA
W3CHINA Blog 0.8 Processed in 0.539 second(s), page refreshed 144800188 times.
《全国人大常委会关于维护互联网安全的决定》  《计算机信息网络国际联网安全保护管理办法》
苏ICP备05006046号