`
yiyeqinghuasoon
  • 浏览: 643929 次
文章分类
社区版块
存档分类
最新评论

C++ 中友元的一些总结

 
阅读更多

1,friend申明一个友元

friend一般为一句申明式,它位于一个类的内部,它申明一个类或者一个函数为该类的友元。 friend并不是定义一个成员函数,所以 friend放在public,protected或者private前都可以,完全是一样的。做为一个友元,即表示在该类或者该函数内部可以访问这个类 的私有成员,你和朋友之间是不是应该没有什么隐藏的呢。例子:

class A

{

public:

A(int _a) : a(_a) {}

friend void test(A&);

friend class B;

private:

int a;

};

void test(A& x)

{

x.a=100;//拥有私有成员a的访问权限

}

class B

{

public:

void foo();

};

如果friend申明式为一般的非模板类或者函数,则该处可以为首次申明。对于一个类,只能是申明式,对于函数,可以是它的定义式。

class A

{

public:

A(int _a) : a(_a) {}

friend void test(A& x)

{

x.a = 100;//定义::test()友元函数

}

friend class B;

private:

int a;

};

注意尽管将函数的定义式放在类内部,但它并不是一个成员函数,对于省略受限的定义形式它将成为一个全局函数::test(),当然你也可以申明另外一个类的成员函数为友元,如:

class A

{

public:

A(int _a) : a(_a) {}

friend void B::foo();

private:

int a;

};

总的来说,如果你想在哪里访问类A的私有成员,就在类A内写上一句该处的申明式,并在前面加上friend关键字。

这是一般情况,很简单,但是它会破坏封装的初衷,所以尽量少用;Effective C++ 中有一个应用的例子,对一个类定义的二元操作符,如果你希望它能对操作数都进行隐式转化,那么就定义一个全局函数,并申明成该类的友元。

2,模板函数作友元

先给一个模板函数,它是一个模板,并不是一个函数:

1

2

template<typename T>

void foo1(T);

在定义foo1为某类的友元时,或者要实例化模板参数T,或者给出可演绎的申明式,而且就算是可以演绎的,一对尖括号也不能省。如:

class A

{

public:

friend void foo1<char>(char);

friend void foo1<>(double);

};

或者给出限制符:::

class A

{

public:

friend void ::foo1(char);

};

当然,如果有一般函数具有这种形式,那会优先于模板函数匹配。最后这里的申明式都不能是定义式,必须前至申明(定义)。

3,模板类里的友元

模板类里也能申明2中的友元,但是模板类有模板参数,如果利用了这个模板参数的友元申明,就属这种情形。

template<typename T>

class A

{

public:

friend void foo1<T>(T);

};

但是,在这里,必须要求foo1在这里是可见的,即不能是首次申明式。如果不使用模板参数,那会是一种有趣的情形。

template<typename T>

class A

{

public:

friend void foo(){}

};

注意这里是一个定义式,它定义了一个::foo()函数为该模板类的友元,在该模板类具现的时候,::foo()也被具现出来,即:

A<int> a1;// ::foo()首次定义

A<char> a2;// ::foo()第二次定义,违背C++一次定义原则

4,友元模板

如果想定义一系列函数为该类的友元,可以使用友元模板。它和模板的申明式类似,只是在template<>后加了friend关键字。

class A

{

public:

template<typename T>

friend void foo();

};

5,能否做为定义式

能做为定义式的情况是:非受限,没有前至::,没有模板参数列表,没一对尖括号。如果是模板申明式,不能是首次申明,在该处必须是可见的。

6,一个完整的例子

template<typename T>

class Rat

{

public:

Rat(T _a, T _b) : a(_a), b(_b) {}

friend Rat<T> operator*<T>(Rat<T>&,Rat<T>&);

private:

T a,b;

};

template<typename T>

Rat<T> operator*(Rat<T> & x, Rat<T> & y)

{

return Rat<T>(x.a*y.a,x.b*y.b);

}

Rat< T >为T类型的有理数类,定义它的相乘运算,定义一个全局函数,并申明为友元,该函数也应该是模板,希望有如上的程序通过编译。在friend式之前没有operator*()的申明,所以这里不能是首次申明,在前面必须加上申明式:

template<typename T>

Rat<T> operator*(Rat<T> & x, Rat<T> & y);

在这之前又没有Rat的申明,再加上:

template<typename T>

class Rat;

通过编译,或者改成友元模板:

template<typename T>

class Rat

{

public:

Rat(T _a, T _b) : a(_a), b(_b) {}

template<typename UU>

friend Rat<UU> operator*(Rat<UU>&,Rat<UU>&);

private:

T a,b;

};

template<typename T>

Rat<T> operator*(Rat<T> & x, Rat<T> & y)

{

return Rat<T>(x.a*y.a,x.b*y.b);

}

有 细微的不同,Rat< T >申明了一系列友元operator*< UU >,当然没必要,只要 operator*< T >就够了,但是形式上简单一些。还有一种更简单的形式,就是将定义式放在里面,正是Effective C++里使用的方法:

template<typename T>

class Rat

{

public:

Rat(T _a, T _b) : a(_a), b(_b) {}

friend Rat<T> operator*(Rat<T>&x,Rat<T>&y) //定义并申明了::operator*()

{

return Rat<T>(x.a*y.a,x.b*y.b);

}

private:

T a,b;

};

分享到:
评论

相关推荐

    C++中友元的三个例子

    友元的三个例子,比较直观的说明了C++中友元的概念。

    C++中友元的实例详解

    C++中友元的实例详解 尽管友元被授予从外部访问类的私有部分的权限,但他们并不与面向对象的编程思想相悖;相反他提高了公共接口的灵活性。 一、友元类 友元声明可以位于公有、私有活保护部分、其所在位置无关紧要...

    C++ 中友元函数与友元类详解

    主要介绍了C++ 中友元函数与友元类详解的相关资料,需要的朋友可以参考下

    友元类(C++基础教学)

    如何声明和创建友元类 简单友元类的声明,C++中友元类的应用范围

    C++基础-友元专题

    详细介绍了C++中友元的使用,适合C++入门者参考学习。

    C++友员程序

    C++中友员函数的使用举例。以学生老师类为例

    C++友元(Friend)用法实例简介

    相对于Java而言,友元是C++中特有的一种元素,很多教材上对其介绍的相对较少,因此初学的时候往往不能很快掌握,本文总结了友元的用法和一些注意的地方,供大家参考借鉴。希望能对初学C++的朋友起到一点帮助作用。 ...

    在C++中关于友元函数的进一步理解

    今天小编就为大家分享一篇关于在C++中关于友元函数的进一步理解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧

    cpp_200706_友元函数_

    C++中友元函数的例子,可以通过这些例子认识友元函数

    C++学习实例

    C++中友元和重载实例,由求两点的距离说明友元函数的概念和使用。由实例说明++,--重载

    IBM助力中友百货信息化建设

    北京中友百货商场与IBM合作,选择IBMeServerx系列服务器及TotalStorage存储解决方案升级其核心收银系统,从而成为全国零售百货行业首个应用64位工业标准服务器平台的大型商家。

    卖场布局:台湾中友百货的卫生间设计

    超市管理的目标基本以消费者对象而确定,提供的卖场布局:台湾中友百货的卫生间设计能够给你学...该文档为卖场布局:台湾中友百货的卫生间设计,是一份很不错的参考资料,具有较高参考价值,感兴趣的可以下载看看

    探究网络安全态势感知系统关键技术.pdf

    探究网络安全态势感知系统关键技术.pdf

    java 中的经典递归

    经典递归!!中友很多经典的递归我们不防来看看

    用友t3操作流程

    中友操作环境的安装及操作详细,又规范的符合了大中小型企业,为单位会计合理

    长纤维增强聚酰胺制件翘曲因素的正交实验研究

    长纤维增强聚酰胺制件翘曲因素的正交实验研究,曹文钢,吴中友,翘曲变形是塑料制件常见的缺陷之一,导致翘曲变形的因素有很多且影响大小也不一样。本文研究了模具温度、熔体温度、开模时间、注

    Yii相关资料

    它将 Web 编程中的可重用性发挥到极致,能够显著加速开发进程。Yii(读作“易”)代表简单(easy)、高效(efficient)、可扩展...此资源中友Yii安装包,Yii API,Yii 使用手册、文档以及多本Yii相关的PDF电子书。

    java版斗地主源码-Under-HuLuWa:Java游戏

    每名人物拥有武力、智力、护甲、魔抗、速度和攻击范围共计六项属性,技能也分为物理伤害与魔法伤害,此外,游戏过程中友方或敌方会对自己施加buff从而改变属性,机智的利用各项属性去击败对手是一个不错的策略,比如...

Global site tag (gtag.js) - Google Analytics