剖析C++编程中friend关键字所修饰的友元函数和友元类

 更新时间:2016年01月21日 15:33:43   投稿:goldensun  
这篇文章主要介绍了剖析C++编程中friend关键字所修饰的友元函数和友元类,友元了以后在外部就可以访问到正常情况下无法访问到的私有属性和方法,需要的朋友可以参考下

在某些情况下,为不是类成员的函数或单独类中的所有函数授予成员级别的访问权会更方便。仅类实现器可以声明其友元。函数或类不能将其自身声明为任何类的友元。在类声明中,使用 friend 关键字和非成员函数名称或其他类,以允许其访问你的类的专用和受保护成员。
语法

  friend class-name;
friend function-declarator;

友元声明
如果声明以前未声明的友元函数,则该函数将被导出到封闭非类范围。
友元声明中声明的函数被视为已使用 extern 关键字声明。(有关 extern 的详细信息,请参阅静态存储类说明符。)
尽管具有全局范围的函数可以在其原型之前声明为友元函数,但是成员函数在它们的完整类声明出现前不能声明为友元函数。以下代码演示此失败的原因:

class ForwardDeclared; // Class name is known.
class HasFriends
{
 friend int ForwardDeclared::IsAFriend(); // C2039 error expected
};

前面的示例将类名 ForwardDeclared 输入到范围中,但是完整的声明(具体而言,声明函数 IsAFriend 的部分)是未知的。因此,friend 类中的 HasFriends 声明会生成一个错误。
若要声明两个互为友元的类,则必须将整个第二个类指定为第一个类的友元。此限制的原因是该编译器仅在声明第二个类的位置有足够的信息来声明各个友元函数。
注意
尽管整个第二个类必须是第一个类的友元,但是可以选择将第一个类中的哪些函数作为第二个类的友元。
友元函数
friend 函数是一个不为类成员的函数,但它可以访问类的私有和受保护的成员。友元函数不被视为类成员;它们是获得了特殊访问权限的普通外部函数。友元不在类的范围内,除非它们是另一个类的成员,否则不会使用成员选择运算符(. 和 –>)调用它们。 friend 函数由授予访问权限的类声明。可将 friend 声明放置在类声明中的任何位置。它不受访问控制关键字的影响。
以下示例显示 Point 类和友元函数 ChangePrivate。 friend 函数可以访问其接受为参数的 Point 对象的私有数据成员。

// friend_functions.cpp
// compile with: /EHsc
#include <iostream>

using namespace std;
class Point
{
 friend void ChangePrivate( Point & );
public:
 Point( void ) : m_i(0) {}
 void PrintPrivate( void ){cout << m_i << endl; }

private:
 int m_i;
};

void ChangePrivate ( Point &i ) { i.m_i++; }

int main()
{
 Point sPoint;
 sPoint.PrintPrivate();
 ChangePrivate(sPoint);
 sPoint.PrintPrivate();
// Output: 0
   1
}
作为友元的类成员
类成员函数可以声明为其他类中的友元。请看下面的示例:
// classes_as_friends1.cpp
// compile with: /c
class B;
class A {
public:
 int Func1( B& b );
private:
 int Func2( B& b );
};
class B {
private:
 int _b;
 // A::Func1 is a friend function to class B
 // so A::Func1 has access to all members of B
 friend int A::Func1( B& );
};
int A::Func1( B& b ) { return b._b; } // OK
int A::Func2( B& b ) { return b._b; } // C2248

在前面的示例中,仅为函数 A::Func1( B& ) 授予对类 B 的友元访问权限。因此,访问私有成员 _b 在类 Func1 的 A 中是正确的,但在 Func2 中是不正确的。
friend 类是其所有成员函数都是类的友元函数的类,即,其成员函数具有对类的私有成员和受保护成员访问权限。假定类 friend 中的 B 声明是:

friend class A;

在这种情况下,将为类 A 中所有成员函数授予对类 B 的友元访问权限。以下代码是友元类的示例:

// classes_as_friends2.cpp
// compile with: /EHsc
#include <iostream>

using namespace std;
class YourClass {
friend class YourOtherClass; // Declare a friend class
public:
 YourClass() : topSecret(0){}
 void printMember() { cout << topSecret << endl; }
private:
 int topSecret;
};

class YourOtherClass {
public:
 void change( YourClass& yc, int x ){yc.topSecret = x;}
};

int main() {
 YourClass yc1;
 YourOtherClass yoc1;
 yc1.printMember();
 yoc1.change( yc1, 5 );
 yc1.printMember();
}

友元关系不是相互的,除非如此显式指定。在上面的示例中,YourClass 的成员函数无法访问 YourOtherClass 的私有成员。
托管类型不能具有任何友元函数、友元类或友元接口。
友元关系不能继承,这意味着从 YourOtherClass 派生的类不能访问 YourClass 的私有成员。友元关系不可传递,因此 YourOtherClass 的友元类无法访问 YourClass 的私有成员。
下图显示了 4 个类声明:Base、Derived、aFriend 和 anotherFriend。只有类 aFriend 具有对 Base 的私有成员(以及对 Base 可能已继承的所有成员)的直接访问权限。

2016121153215228.jpeg (552×192)

内联友元定义
可以在类声明中定义友元函数。这些函数是内联函数,类似于成员内联函数,其行为就像它们在所有类成员显示后但在类范围关闭前(类声明的结尾)被定义时的行为一样。
类声明中定义的友元函数不被认为在封闭类的范围内;它们在文件范围内。

相关文章

  • 浅析C语言位域和位段

    浅析C语言位域和位段

    以下是对C语言中的位域和位段进行了详细的分析介绍,需要的朋友可以过来参考下
    2013-08-08
  • C语言中对数组赋值的三种形式

    C语言中对数组赋值的三种形式

    这篇文章主要给大家介绍了关于C语言中对数组赋值的3种形式,文中通过示例代码介绍的非常详细,对大家学习或者使用C语言具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-09-09
  • 北邮考研复试C语言上机题目精选

    北邮考研复试C语言上机题目精选

    这篇文章主要介绍了北邮考研复试C语言上机题目精选,摘自2010年北邮CS的复试,需要的朋友可以参考下
    2015-08-08
  • Qt Quick Designer灰色或者禁用的解决

    Qt Quick Designer灰色或者禁用的解决

    本文主要介绍了Qt Quick Designer灰色或者禁用的解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-02-02
  • 一些C语言中字符串的算法问题解决实例小结

    一些C语言中字符串的算法问题解决实例小结

    这篇文章主要介绍了一些C语言中字符串的算法问题解决实例小结,包括将字符串转化为int类型的数及旋转字符串等操作,需要的朋友可以参考下
    2016-03-03
  • 判断一个数是不是素数的方法

    判断一个数是不是素数的方法

    判断一个数是不是素数的方法,需要的朋友可以参考一下
    2013-03-03
  • C语言的多级指针你了解吗

    C语言的多级指针你了解吗

    这篇文章主要介绍了C语言中的多级指针,本文给大家介绍的非常详细,具有参考借鉴价值,需要的朋友可以参考下,希望能给你带来帮助
    2021-08-08
  • C++无锁数据结构实现示例详解

    C++无锁数据结构实现示例详解

    这篇文章主要为大家介绍了C++无锁数据结构实现示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12
  • Clion-MinGW编译后的exe文件添加ico图标的操作方法

    Clion-MinGW编译后的exe文件添加ico图标的操作方法

    这篇文章主要介绍了Clion-MinGW编译后的exe文件添加ico图标的操作方法,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-07-07
  • Qt QCompleter自动补全的实现

    Qt QCompleter自动补全的实现

    本文主要介绍了Qt QCompleter自动补全的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-04-04

最新评论