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

2020-01-06 14:28:42王旭
作为友元的类成员
类成员函数可以声明为其他类中的友元。请看下面的示例:

// 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 可能已继承的所有成员)的直接访问权限。

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

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