C++的友元声明

C++的友元声明

友元声明出现于类体内,并向一个函数或另一个类授予对包含友元声明的类的私有及受保护成员的访问权。

语法及描述
// (1)friend 函数声明,指明函数为此类的友元
class Y {
    int data; // 私有成员
    // 非成员函数的运算符 operator<< 将拥有对 Y 的私有成员的访问权
    friend std::ostream& operator<<(std::ostream& out, const Y& o);
    friend char* X::foo(int); // 其他类的成员亦可为友元
    friend X::X(char), X::~X(); // 构造函数与析构函数亦可为友元
};
// 友元声明不声明成员函数
// 此 operator<< 仍需定义,作为非成员
std::ostream& operator<<(std::ostream& out, const Y& y)
{
    return out << y.data; // 可访问私有成员 Y::data
}
 
 
 
// (2)friend 函数定义,(只允许在非局部类的定义中使用)定义一个非成员函数,同时令其为此类的友元。这种非成员函数始终为内联函数
class X {
    int a;
    friend void friend_set(X& p, int i) {
        p.a = i; // 此为非成员函数
    }
public:
    void member_set(int i) {
        a = i; // 此为成员函数
    }
};
 
 
 
// (3)friend 详述类说明符,指定以详述类说明符指名的 class、struct 或 union 为此类的友元。这意味着,该友元的各成员声明和定义可以访问此类的私有与受保护成员,而且该友元也能从此类的私有或受保护成员进行继承。 不需要提前声明用于此友元声明的类名
 
 
 
// (4)(C++11 起) friend 简单类型说明符,friend typename-说明符,若该类型是(可有 cv 限定的)class、struct 或 union,则为此类的友元;否则忽略该 friend 声明。此声明不前置声明新类型。     
class Y {};
class A {
    int data; // 私有数据成员
    class B { }; // 私有嵌套类型
    enum { a = 100 }; // 私有枚举项
    friend class X; // 友元类的前置声明(详述类型说明符)
    friend Y; // 友元类声明(简单类型说明符) (C++11 起)
};
 
class X : A::B // OK:友元能访问 A::B
{
    A::B mx; // OK:友元的成员能访问 A::B
    class Y {
        A::B my; // OK:友元的嵌套成员能访问 A::B
    };
    int v[A::a]; // OK:友元的成员能访问 A::a
};
注意事项

友元关系不传递(你朋友的朋友不是你的朋友)。

友元关系不继承(你朋友的孩子不是你的朋友)。

友元函数声明中不允许使用存储类说明符。在友元声明中定义的函数具有外部连接,先前已定义的函数保持其定义时所具有的连接。

访问说明符对于友元声明的含义没有影响(它们可出现于 private: 或于 public: 节,且并无区别)

友元类声明不能定义新的类(friend class X {}; 是错的)

当局部类将一个无限定的函数或类声明为其友元时,只查找在其最内层非类作用域中的函数与类,而非全局函数:

class F {};
int f();
int main()
{
    extern int g();
    class Local { // main() 函数中的局部类
        friend int f(); // 错误,没有声明于 main() 的该函数
        friend int g(); // OK,main() 中有 g 的声明
        friend class F; // 令局部 F(随后定义)为友元
        friend class ::F; // 令全局 F 为友元
    };
    class F {}; // 局部 F
}

你可能感兴趣的:(C++,c++,类)