关于友元函数和友元类作用的讨论!

transformers 2004-01-13 12:15:10
请大家各抒己见,共同讨论一下关于友元函数和友元类的应用(什么时候用?怎么用?为什么要用?等···)
...全文
1664 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
newkaka1981 2004-01-18
  • 打赏
  • 举报
回复
回复人: transformers() ( ) 信誉:100 2004-01-17 17:08:00 得分:0
“A可以被实例化,但是不能被继承”为什么不能被继承???
====================================
确切地说,A可以被继承,但是继承了A的类不能被实例化(那这个类也就没用了)。假设有
class E:public A{};
则实例化E时:
E e;
系统将报告无法进入B的私有成员声明而无法通过编译。

这是因为 A是 virtual 继承 B的,所以,E再继承A的时候,需要由E去调用B的构造函数,但是E不是B的友元,所以无法编译通过

但是如果A不是virtual继承B的,那么E再继承A时,构造函数的调用情况是E调用父类A的构造函数,A再调用A的父类B的构造函数,而A是其父类B的友元,所以这一串调用能够顺利进行。
Leung_ 2004-01-17
  • 打赏
  • 举报
回复
friend关键字尽量少用,使class就是为了将一些数据封装起来,而friend无疑破坏了class的存取权限。
chon81 2004-01-17
  • 打赏
  • 举报
回复
须要的时候就用了.
哪那么多规具啊.
transformers 2004-01-17
  • 打赏
  • 举报
回复
“A可以被实例化,但是不能被继承”为什么不能被继承???
newkaka1981 2004-01-17
  • 打赏
  • 举报
回复
Mephisto_76(湮没骑士) ,你的方法(定义一个不能被继承的类B)还没有说完,我来补全:)——
定义:
class B
{
private:
B()
{
}
friend class A;
};
将导致B无法被除A以外的其它任何class直接继承以后实例化,也就是说,在上面这个定义的基础上,如果你在定义:
class C:public B{};
将导致编译能够通过,但是无法实例化C(那当然也没用了,所以间接实现了一个无法继承的类B),但是因为A是B的友元,所以能够进入B的private区域,所以如果定义:
class A:public B{};
能够实例化A.

但是这样定义还有一个漏洞,如果在A普通public继承B的基础上再定义:
class D:public A{};
你会发现D也是可以实例化的,那么相当于间接public继承了B。这显然不是我们想要的,所以,正确的做法是(完整代码):

class A;
class B
{
private:
B()
{
}
friend class A;
};

class A:virtual public B{}; //A is the one we're looking for

也就是说要做到三步:
1)将你B的相关构造函数放入private区域
2)声明子类A为B的友元
3)定义A为virtual public继承B

这样创建的代码的效果是:
B不能被继承也不能被实例化
A可以被实例化,但是不能被继承

所以,最后创建出来的A才是真正我们想要得到的对象
zhaopeng3 2004-01-16
  • 打赏
  • 举报
回复
引自EffectiveC++2/e
如果函数F需要再其最左端引数上施行型别转换,请让F成为一个non-member function;
如果函数F还必须取用类的非public成员,请让F成为一个friend;
Mephisto_76 2004-01-15
  • 打赏
  • 举报
回复
上面写错了:
应该是:

class B
{
private:
B()
{
}
friend claa A;
};
Mephisto_76 2004-01-15
  • 打赏
  • 举报
回复
#include <iostream>

class A
{
public:
A()
{
b_ = new B;
}

~A()
{
if( 0 != b_ )
{
delete b_;
b_ = 0;
}
}
private:
B* b_;
};

class B
{
private:
B()
{
}
};

这样就可以定义一个不能被继承的类B。
zhaochong12 2004-01-14
  • 打赏
  • 举报
回复
破坏我的封装性的小家伙.... 给我自己留下后门的小帮手~
autoegg 2004-01-13
  • 打赏
  • 举报
回复
友元类破坏封装等等是毫无疑问的,然而它也有自己的用途,比如实现某个抽象发布概念时可以用两个类实现,如Aimp类和A类,在Aimp类中把A类设为友类,把不想被发布者知道的信息藏在Aimp类中,可以在升级版本时有助于提高被发布对象(用户)的易用性。
sevencat 2004-01-13
  • 打赏
  • 举报
回复
一个例子:

线程池的管理。

线程不能由用户创建和DELETE,而只能由线程池类创建和DELETE,这样就可以把线程池设为线程的友元类,并将其构造构析函数设为私有。
liuheliaoshi7879 2004-01-13
  • 打赏
  • 举报
回复
友元有点突破了面向对象思想的封装性,用起来确实是方便,是用来偷懒的良好工具
byyyyy 2004-01-13
  • 打赏
  • 举报
回复
如果只是一般函数访问类的私有成员或者说是私有数据成员,使用友元函数就可以了,如果是使用类来访问其它类的私有数据成员和私有成员函数就使用友元类.
阿发伯 2004-01-13
  • 打赏
  • 举报
回复
同意上面的观点,友元要少用,或者说不要乱用,能不用尽量不用,除非2者联系紧密不可分,如链表、树的节点类,因为与链表、树的联系太紧,非得用友元不可
redhat_xu 2004-01-13
  • 打赏
  • 举报
回复
首先我说一下:
友元的产生是由于最初电脑的运行速度没有现在快,而C++语言讲的就是速度,为了解决其它类方便访问类的私有变量或者说是私有成员函数,故就使用了友元这个机制,但是现在的电脑速度的提高,友元所产生的作用也渐渐地看不出效果来了,但是C++标准没有把友元取消.
友元不是成员函数,但是它可以访问类中的私有成员。友元的作用在于提高程序的运行效率,但是,它破坏了类的封装性和隐藏性,使得非成员函数可以访问类的私有成员。
下面说一下什么时候使用友元函数和友元类,其实二者没有太大的区别,如果只是一般函数访问类的私有成员或者说是私有数据成员,使用友元函数就可以了,如果是使用类来访问其它类的私有数据成员和私有成员函数就使用友元类.
小李匪盗 2004-01-13
  • 打赏
  • 举报
回复
用友元可以偷懒
fireseed 2004-01-13
  • 打赏
  • 举报
回复
不同的设计模式有不同的用处,楼主的论题太宽,不好
clancy 2004-01-13
  • 打赏
  • 举报
回复
友元是一种定义在类外部的普通函数,但它需要在类体内进行说明,为了与该类的成员函数加以区别,在说明时前面加以关键字friend。友元不是成员函数,但是它可以访问类中的私有成员。友元的作用在于提高程序的运行效率,但是,它破坏了类的封装性和隐藏性,使得非成员函数可以访问类的私有成员。
Wolf0403 2004-01-13
  • 打赏
  • 举报
回复
如果不是这两个类(或一个类与一个函数)之间的关系非常紧密,就不应该用友元吧?
shuneng 2004-01-13
  • 打赏
  • 举报
回复
少用,朋友太多不是好事。把内部的都公开了有DANGER的呢。
一般对于OPERATOR的话,如果可以重载完成任务尽可能少用友元。
当一个函数需要方便显式地使用类的数据成员的话就写一个吧~~

64,666

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧