C++友元

来源:互联网 发布:山东自动化控制软件 编辑:程序博客网 时间:2024/05/22 05:08

http://www.cppblog.com/deercoder/archive/2010/01/12/105530.aspx

C++友元的一个问题-----------由派生类访问基类的私有成员继承是一个永恒的话题,可是带来的问题却也是多多啊。最近一直在思考一些细节的东西,于是也有了不少收获。今天,当我想要用派生类访问基类的私有成员时,发现问题了……代码1:(没有问题,对照下面的代码来看错误之处) 1#include <iostream> 2using namespace std; 3class B; 4class A{ 5int b; 6public: 7  friend class B; 8  int a; 9  A(int x):a(x) { b = a+1;}10};11class B:public A{12public:13  void print();14    B(int x):A(x){} //基类定义了一个有参的构造函数时,派生类必须定义构造函数 15};16void B::print()17{ 18  cout << B::a << endl;19  cout << B::b << endl;20}2122int main()23{24B b(4);25b.print();26}27这里可以看到,结果是正确的,而且还能够访问到基类的私有成员b,证明了自己的想法。其中,将派生类都作为了基类的友元,这个范围未免有点大了,好吧,我缩小点,(问题来了……)问题代码: 1#include <iostream> 2using namespace std; 3class B; 4class A{ 5int b; 6public: 7  int a; 8  A(int x):a(x) { b = a+1;} 9  friend void B::print(); 10};11class B:public A{12public:13  void print();14  B(int x):A(x){} //基类定义了一个有参的构造函数时,派生类必须定义构造函数 15};161718void B::print()19{ 20  cout << B::a << endl;21  cout << B::b << endl;22}2324int main()25{26B b(4);27b.print();28}变化后的代码仅仅就是将类B的print函数作为基类A的友元,这样,按照道理来说,应该也是可以访问基类的私有成员的。而且从上面那个正确的代码来看,声明为友元之后,确实是可以突破访问权限的,然后,此代码有错误,显示的就是私有成员的不可访问。一时间感觉世界有点不真实了…………-------------------------------目前原因正在思考中,如果哪个过客知道答案,后者有自己的见解,不妨占用下你宝贵的时间,留个言吧。(注记:个人认为,印象中《C++ Primer》中讲到在声明类的成员函数为另外一个类的友元时,需要先定义这个类,而如果是派生类的话,可以声明下,等后来再定义。这个也是代码1的做法,没有问题。所以我觉得可能是如果用下面的代码,那么没有先定义类B,而声明了它的成员函数print,所以有问题。待求证……)结束:感谢Sunshine Alike  ,我觉得他的解释可能是比较合理的,摘抄如下,如果有误,欢迎留言指正。。代码2中,仅仅声明类B是无法得知类内部具体实现的,所以你这个时候指定B中的一个函数作为友元是不行的,因为在这个时候编译器还不知道B的具体实现是怎么样的。代码1:开始时声明类B,将其整个类作为友元类,编译器无需知道其内部实现,所以可以通过posted on 2010-01-12 23:53 deercoder 阅读(2172) 评论(10)  编辑 收藏 引用评论:# re: C++友元的一个问题-----------由派生类访问基类的私有成员 2010-01-13 01:15 | zhaoyg刚才在看到friend void B::print(); 这句时就已经觉得问题就是由他引发的。 因为我记得如果是要将类的成员作为友元,那该类就应该是已定义的。 经编译,得到验证 报错如下: error: member `void B::print()' declared as friend before type `B' defined C++ Primer 上也说得是“必须先定义一个类,才能将成员函数设为友元” 还有, “而如果是派生类的话,可以声明下,等后来再定义” 这句话我没有在C++ Primer 上找到。  回复  更多评论# re: C++友元的一个问题-----------由派生类访问基类的私有成员 2010-01-13 10:39 | 刘畅@zhaoyg 谢谢你的回答。 对于这个错误,我开始的看法和你是一样的,认为必须先要定义一个类,然后再可以声明它的函数是另一个类的友元。 可是,看看前面的代码1我就觉得有点不对,因为对于class B,先开始的时候只是声明,而没有定义,这样却可以将整个类作为它的友元,我觉得也有点不可行。不然,这样不是和上面的一个道理吗?  回复  更多评论# re: C++友元的一个问题-----------由派生类访问基类的私有成员 2010-01-13 11:18 | Sunshine Alike@刘畅代码2中,仅仅声明类B是无法得知类内部具体实现的,所以你这个时候指定B中的一个函数作为友元是不行的,因为在这个时候编译器还不知道B的具体实现是怎么样的。代码1:开始时声明类B,将其整个类作为友元类,编译器无需知道其内部实现,所以可以通过  回复  更多评论# re: C++友元的一个问题-----------由派生类访问基类的私有成员 2010-01-13 12:31 | 刘畅@Sunshine Alike 有道理,其实前面也觉得可能跟类的实现有关吧,学习了~~~  回复  更多评论# re: C++友元的一个问题-----------由派生类访问基类的私有成员 2010-09-21 07:39 | @kll友元的访问权限 与类的继承你搞混了  回复  更多评论# re: C++友元的一个问题-----------由派生类访问基类的私有成员 2010-09-21 07:51 | @kll原来不注册可以留言 呵呵 上面说的只是测试 下面说下我理解不知道对不对 code1 中将类B设为A的友元 B又是A的public继承 那么B能访问A的private成员是因为友元的缘故 B::b等价于 B:: A::b 故B.print() 可以执行 code2 只是将B的成员print()设为A的友元 那么B::b 则不成立 无法访问吧 若是 print 函数带A对象的引用会通过的 我了解的这一点不多 其实我是想查询关于公有派生类的友元 能不能访问基类的private的成员 或者访问权限到那一层 在继承层次中友元的权限又有哪些 这方面的文章 如果斑竹有资料 望不吝赐教 谢谢 忘了打标点 估计看起来麻烦 呵呵 我没有代码运行的环境 要不然能测试了 呵呵  回复  更多评论# re: C++友元的一个问题-----------由派生类访问基类的私有成员 2014-01-12 12:51 | panpan为什么我将第一种的 A(int x):a(x) { b = a+1;}改为A(int x):a(x),b(a+1) {}运行结果为4-858993459请按任意键继续. . .为什么 搞不清楚  回复  更多评论# re: C++友元的一个问题-----------由派生类访问基类的私有成员 2014-01-12 12:53 | panpan哦哦 搞懂了 成员变量是按照在类中声明的先后顺序来初始化的   回复  更多评论# re: C++友元的一个问题-----------由派生类访问基类的私有成员 2014-01-12 13:32 | panpan我觉得这个派生类成员函数作为基类的成员友元本身就有问题,首先,类B是类A的派生类,那么类A必须在类A前定义,而派生类B的函数print()是基类友元,使得派生类B必须先于A定义(不是声明),这两个前提条件已经互相矛盾,所以怎么都是有问题的  回复  更多评论# re: C++友元的一个问题-----------由派生类访问基类的私有成员 2014-01-12 13:56 | panpan我试了 第二种情况 即便是传给print()一个A&参数,照样是不能访问b成员变量的 这个确实没想通  回复  更多评论
0 0