[c++读书笔记]friend的注意事项 |
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
|
阅读全文(3934) | 回复(1) | 编辑 | 精华 |
回复:friend的注意事项 |
C++太难学了,学不会阿,还是java好学
|
个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除 |
回复:friend的注意事项 |
Jeffern(游客)发表评论于2006/10/28 15:44:46 | 最近在业务上很用功!
|
个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除 | » 1 »
|
« | October 2025 | » | 日 | 一 | 二 | 三 | 四 | 五 | 六 | | | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | | |
|
公告 |
有一种鸟儿是永远关不住的 因为它的每片羽翼上都沾满了自由的光辉
方向:计算机视觉 人工智能 演化算法
| |
Blog信息 |
blog名称:阳光海岸心 日志总数:166 评论数量:237 留言数量:-4 访问次数:1459083 建立时间:2006年6月2日 | |

|