友元_友元函数 - CSDN
精华内容
参与话题
  • C++友元函数和友元类用法详解

    万次阅读 多人点赞 2018-01-21 21:12:37
    在C++中,我们使用类对数据进行了隐藏和封装,类的数据成员一般都...除了友元函数外,还有友元类,两者统称为友元友元的作用是提高了程序的运行效率(即减少了类型检查和安全性检查等都需要时间开销),但它破坏了类

     在C++中,我们使用类对数据进行了隐藏和封装,类的数据成员一般都定义为私有成员,成员函数一般都定义为公有的,以此提供类与外界的通讯接口。但是,有时需要定义一些函数,这些函数不是类的一部分,但又需要频繁地访问类的数据成员,这时可以将这些函数定义为该函数的友元函数。除了友元函数外,还有友元类,两者统称为友元。友元的作用是提高了程序的运行效率(即减少了类型检查和安全性检查等都需要时间开销),但它破坏了类的封装性和隐藏性,使得非成员函数可以访问类的私有成员。

    友元函数 : 
           友元函数是可以直接访问类的私有成员的非成员函数。它是定义在类外的普通函数,它不属于任何类,但需要在类的定义中加以声明,声明时只需在友元的名称前加上关键字friend,其格式如下:
           friend 类型 函数名(形式参数);
           友元函数的声明可以放在类的私有部分,也可以放在公有部分,它们是没有区别的,都说明是该类的一个友元函数。
           一个函数可以是多个类的友元函数,只需要在各个类中分别声明。
           友元函数的调用与一般函数的调用方式和原理一致。
    友元类 : 
           友元类的所有成员函数都是另一个类的友元函数,都可以访问另一个类中的隐藏信息(包括私有成员和保护成员)。       
           当希望一个类可以存取另一个类的私有成员时,可以将该类声明为另一类的友元类。定义友元类的语句格式如下:
           friend class 类名;
           其中:friend和class是关键字,类名必须是程序中的一个已定义过的类。

    例如,以下语句说明类B是类A的友元类:
           class A
           {
                  …
           public:
                  friend class B;
                  …
           };
           经过以上说明后,类B的所有成员函数都是类A的友元函数,能存取类A的私有成员和保护成员。

           使用友元类时注意:
                 (1) 友元关系不能被继承。 
                 (2) 友元关系是单向的,不具有交换性。若类B是类A的友元,类A不一定是类B的友元,要看在类中是否有相应的声明。
                 (3) 友元关系不具有传递性。若类B是类A的友元,类C是B的友元,类C不一定是类A的友元,同样要看类中是否有相应的申明
    《windows环境多线程编程原理与应用》中解释:
      如果将类的封装比喻成一堵墙的话,那么友元机制就像墙上了开了一个门,那些得
      到允许的类或函数允许通过这个门访问一般的类或者函数无法访问的私有属性和方   
      法。友元机制使类的封装性得到消弱,所以使用时一定要慎重。

    友元类:

    将外界的某个类在本类别的定义中说明为友元,那么外界的类就成为本类的“朋  
       友”,那个类就可以访问本类的私有数据了。
       class Merchant
          {
              private :
                 int m_MyMoney;
                 int m_MyRoom;
                 … …
              Public:
                 Friend class Lawyer;
                 Int getmoney();
                 … …
          };
          Class Lawyer
         {
            Private:
              … …
            Public:
             … …
         };
         只有你赋予某个类为你的友元时,那个类才有访问你的私有数据的权利。说明一个函数为一个类的友元函数则该函数可以访问此类的私有数据和方法。定义方法是在类的定义中,在函数名前加上关键字friend.

    需要友元与友元的优缺点: 

           通常对于普通函数来说,要访问类的保护成员是不可能的,如果想这么做那么必须把类的成员都生命成为public(共用的),然而这做带来的问题遍是任何外部函数都可以毫无约束的访问它操作它,c++利用friend修饰符,可以让一些你设定的函数能够对这些保护数据进行操作,避免把类成员全部设置成public,最大限度的保护数据成员的安全。 

            友元能够使得普通函数直接访问类的保护数据,避免了类成员函数的频繁调用,可以节约处理器开销,提高程序的效率,但所矛盾的是,即使是最大限度大保护,同样也破坏了类的封装特性,这即是友元的缺点,在现在cpu速度越来越快的今天我们并不推荐使用它,但它作为c++一个必要的知识点,一个完整的组成部分,我们还是需要讨论一下的。 在类里声明一个普通数学,在前面加上friend修饰,那么这个函数就成了该类的友元,可以访问该类的一切成员。

            下面我们来看一段代码,看看我们是如何利用友元来访问类的一切成员的:

    #include <iostream> 
    using namespace std; 
    class Internet 
    { 
    public: 
    Internet(char *name,char *address) // 改为:internet(const char *name , const char *address)
    { 
    strcpy(Internet::name,name); 
    strcpy(Internet::address,address); 
    } 
    friend void ShowN(Internet &obj);   //友元函数的声明 
    public:              // 改为:private
    char name[20]; 
    char address[20]; 
    }; 
    void ShowN(Internet &obj)        //类外普通函数定义,访问a对象的保护成员name,不能写成,void Internet::ShowN(Internet &obj) 
    { 
    cout<<obj.name<<endl;          //可访问internet类中的成员
    } 
    void main() 
    { 
    Internet a("谷歌","http://www.google.cn/";); 
    ShowN(a); 
    cin.get(); 
    } 
    
          示例2:

          分别定义一个类A和类B ,各有一个私有整数成员变量通过构造函数初始化;类A有一个成员函数Show(B &b)用来打印A和B的私有成员变量,请分别通过友元函数和友元类来实现此功能。使用友元类 和 友元函数实现:

    #include <iostream>
    
    using namespace std;
    class B;
    class A;
    void Show( A& , B& );
    
    class B
    {
    private:
    int tt;
    friend class A;
    friend void Show( A& , B& );
    
    public:
    B( int temp = 100):tt ( temp ){}
    
    };
    
    class A
    {
    private:
    int value;
    friend void Show( A& , B& );
    
    public:
    A(int temp = 200 ):value ( temp ){}
    
    void Show( B &b )
    {
      cout << value << endl;
      cout << b.tt << endl; 
    }
    };
    
    void Show( A& a, B& b )
    {
    cout << a.value << endl;
    cout << b .tt << endl;
    }
    
    int main()
    {
    A a;
    B b;
    a.Show( b );
    Show( a, b );
          return 0;
    }
    



    展开全文
  • 友元

    2019-01-11 11:31:00
    友元主要是为了访问类中的私有成员(包括属性和方法),可以分为友元函数(全局函数),友元类,友元成员函数。 全局函数做友元函数  友元函数是可以直接访问类的私有成员。它是定义在类外的普通函数,它不属于...

      友元主要是为了访问类中的私有成员(包括属性和方法),可以分为友元函数(全局函数),友元类,友元成员函数。

    全局函数做友元函数

      友元函数是可以直接访问类的私有成员。它是定义在类外的普通函数,它不属于任何类,但需要在类的定义中加以声明,声明时在函数名称前加上关键字friend,其格式如下: friend 类型 函数名(形式参数);

      注意:(1)友元函数声明可以在类中的任何地方,一般放在类定义的开始或结尾;(2) 一个函数可以是多个类的友元函数,只需要在各个类中分别声明;(3)友元函数在类内声明,类外定义,定义和使用时不需加作用域和类名,与普通函数无异

     1 class Building{
     2     friend void goodGay(Building * building); //goodGay是Building的友元函数,因此goodGay可以访问building的任意成员
     3 public:
     4     Building(){
     5         m_Sittingroom = "客厅";
     6         m_Bedroom = "卧室";
     7     }
     8 
     9     string m_Sittingroom;
    10 private:
    11     string m_Bedroom;
    12 };
    13 
    14 //和C语言结构体同,传参时尽量不要传递值,尽量传递指针
    15 void goodGay(Building * building){
    16     cout << "别人在访问" << building->m_Sittingroom << endl;
    17     cout << "别人在访问" << building->m_Bedroom << endl; //当不是友元函数时,不能访问私有成员
    18 }
    19 
    20 void test01(){
    21     Building building; //或者Building *build = new Building;这里如果定义指针,需要new,否则未初始化
    22     goodGay(&building);
    23 }

    友元类

      友元类的所有成员函数都是另一个类的友元函数,都可以访问另一个类中的隐藏信息(包括私有成员和保护成员)。当希望一个类可以存取另一个类的私有成员时,可以将该类声明为另一类的友元类。定义友元类的语句格式如下:  friend class 类名;

      注意:(1)友元不可继承;(2)友元是单向的,类A是类B的友元类,但类B不一定是类A的;(3)友元不具有传递性,类A是类B的友元类,类B是类C的友元类,但类A不一定是类C的友元类。

     1 class Building{
     2     friend class Person; //Person是Building的友元函数,因此Person可以访问Building的任意成员
     3 public:
     4     Building(){
     5         this->m_Sittingroom = "客厅";
     6         this->m_Bedroom = "卧室";
     7     }
     8 
     9     string m_Sittingroom;
    10 private:
    11     string m_Bedroom;
    12 
    13 };
    14 
    15 class Person{
    16 
    17 public:
    18     void test(Building *building){
    19         cout << building->m_Bedroom << endl;
    20     }
    21 };
    22 
    23 
    24 void test01(){
    25     Building *build = new Building;//可以在这里写定义,也可以将定义写在Person的构造函数中
    26     Person p;
    27     p.test(build);
    28 }

    友元成员函数

      使类B中的成员函数成为类A的友元函数,这样类B的该成员函数就可以访问类A的所有成员了。

           当用到友元成员函数时,需注意友元声明和友元定义之间的相互依赖,在该例子中,类Person必须先定义,否则类Building就不能将一个Person的函数指定为友元。然而,只有在定义了类Person之后,才能定义类Person的该成员函数。更一般的讲,必须先定义包含成员函数的类,才能将成员函数设为友元。另一方面,不必预先声明类和非成员函数来将它们设为友元。

     1 //和C语言中结构体的互引用类似,需要先声明一个Building类
     2 class Building;
     3 
     4 class Person{
     5 
     6 public:
     7     void test(Building *building); 
     8     void test1(Building *building);
     9 };
    10 
    11 class Building{
    12     friend void Person::test1(Building *building); //先将Person类定义,类友元成员函数声明后,再使用friend
    13 public:
    14     Building(){
    15         this->m_Sittingroom = "客厅";
    16         this->m_Bedroom = "卧室";
    17     }
    18 
    19     string m_Sittingroom;
    20 private:
    21     string m_Bedroom;
    22 
    23 };
    24 
    25 //定义Building类后才能定义Person成员函数
    26 void Person::test1(Building *building){
    27     cout << building->m_Bedroom << endl; 
    28 }
    29 
    30 void Person::test(Building *building){
    31     cout << building->m_Sittingroom << endl;
    32 }
    33 
    34 void test01(){
    35     Building *build = new Building;
    36     Person p;
    37     p.test1(build);
    38 }

      例子中只有test1能访问Building的成员函数,test不能访问。

     

    转载于:https://www.cnblogs.com/qinguoyi/p/10254263.html

    展开全文
  • c++友元函数

    2020-08-29 16:49:19
    目录概述知识点友元函数友元类友成员函数 概述        在C++中,我们使用类对数据进行了隐藏和封装,类的数据成员一般都定义为私有成员,成员函数一般都定义为公有的,以此提供类与外界的通讯...

    概述

           在C++中,我们使用类对数据进行了隐藏和封装,类的数据成员一般都定义为私有成员,成员函数一般都定义为公有的,以此提供类与外界的通讯接口。但是,有时需要定义一些函数,这些函数不是类的一部分,但又需要频繁地访问类的数据成员,这时可以将这些函数定义为该函数的友元函数。除了友元函数外,还有友元类,两者统称为友元。友元的作用是提高了程序的运行效率(即减少了类型检查和安全性检查等都需要时间开销),但它破坏了类的封装性和隐藏性,使得非成员函数可以访问类的私有成员。

    知识点

    • 友元关系不能被继承。
    • 友元关系是单向的,不具有交换性。若类B是类A的友元,类A不一定是类B的友元,要看在类中是否有相应的声明。
    • 友元关系不具有传递性。若类B是类A的友元,类C是B的友元,类C不一定是类A的友元,同样要看类中是否有相应的声明
    • 如果将类的封装比喻成一堵墙的话,那么友元机制就像墙上了开了一个门,那些得到允许的类或函数允许通过这个门访问一般的类或者函数无法访问的私有属性和方法。友元机制使类的封装性得到消弱,所以使用时一定要慎重。
    • 通常对于普通函数来说,要访问类的保护成员是不可能的,如果想这么做那么必须把类的成员都声明为public(共用的),然而这做带来的问题遍是任何外部函数都可以毫无约束的访问它操作它,c++利用friend修饰符,可以让一些你设定的函数能够对这些保护数据进行操作,避免把类成员全部设置成public,最大限度的保护数据成员的安全。
    • 友元能够使得普通函数直接访问类的保护数据,避免了类成员函数的频繁调用,可以节约处理器开销,提高程序的效率,但所矛盾的是,即使是最大限度大保护,同样也破坏了类的封装特性,这即是友元的缺点,在现在cpu速度越来越快的今天我们并不推荐使用它,但它作为c++一个必要的知识点,一个完整的组成部分,我们还是需要讨论一下的。 在类里声明一个普通数学,在前面加上friend修饰,那么这个函数就成了该类的友元,可以访问该类的一切成员

    友元函数

    1. 友元函数是可以直接访问类的私有成员的非成员函数。它是定义在类外的普通函数,它不属于任何类,但需要在类的定义中加以声明
    2. 友元函数的声明可以放在类的私有部分,也可以放在公有部分,它们是没有区别的,都说明是该类的一个友元函数。
    3. 一个函数可以是多个类的友元函数,只需要在各个类中分别声明。
    4. 友元函数的调用与一般函数的调用方式和原理一致。
    class CTestA
    {
    public:
    	CTestA():m_nId(0),m_nAge(0)
    	{}
    
    	friend int Func();//定义为友元函数
    
    private:
    	int m_nId;
    	int m_nAge;
    };
    
    //全局函数
    int Func()
    {
    	CTestA a;
    	return a.m_nId;//可以调用自由成员
    }
    
    int main()
    {
    	int nId = Func();
    	std::cout << nId << std::endl;
    }
    

    友元类

    1. 友元类的所有成员函数都是另一个类的友元函数,都可以访问另一个类中的隐藏信息(包括私有成员和保护成员)。
    2. 当希望一个类可以存取另一个类的私有成员时,可以将该类声明为另一类的友元类。
    class CTestB
    {
    public:
    	friend class CTestA;//把类CTestA定义为类CTestB的友元类,这样就可以在类CTestA中访问类CTestB中的所有成员变量
    
    private:
    	int m_nId;
    	int m_nAge;
    };
    
    class CTestA
    {
    public:
    	CTestA():m_nId(0),m_nAge(0)
    	{}
    
    	void Show() const
    	{
    		//可以在类CTestA中使用CTestB的所有成员变量
    		CTestB b;
    		b.m_nId = 1;
    		b.m_nAge = 2;
    		std::cout << b.m_nId << std::endl;
    	}
    
    private:
    	int m_nId;
    	int m_nAge;
    };
    
    int main()
    {
    	CTestA a;
    	a.Show();//1
    }
    

    友成员函数

    class CTestB
    {
    public:
    	friend void CTestA::Show();//把类CTestA中的Show函数定义为类CTestB的友元函数,这样在类CTestA的Show函数中就可以访问类CTestB的所有成员
    
    private:
    	int m_nId;
    	int m_nAge;
    };
    
    class CTestA
    {
    public:
    	CTestA() :m_nId(0), m_nAge(0)
    	{}
    
    	void Show();
    
    
    private:
    	int m_nId;
    	int m_nAge;
    };
    
    void CTestA::Show()
    {
    	//可以在类CTestA中使用CTestB的所有成员变量
    	CTestB b;
    	b.m_nId = 1;
    	b.m_nAge = 2;
    	std::cout << b.m_nId << std::endl;
    }
    

    参考文章

    展开全文
  • 友元函数

    千次阅读 多人点赞 2018-09-03 10:27:37
    引入友元函数的原因 类具有封装、继承、多态、信息隐藏的特性,只有类的成员函数才可以访问类的私有成员,非成员函数只能访问类的公有成员。为了使类的非成员函数访问类的成员,唯一的做法就是将成员定义为public,...
    • 引入友元函数的原因

      • 类具有封装、继承、多态、信息隐藏的特性,只有类的成员函数才可以访问类的私有成员,非成员函数只能访问类的公有成员。为了使类的非成员函数访问类的成员,唯一的做法就是将成员定义为public,但这样做会破坏信息隐藏的特性。基于以上原因,引入友元函数解决。
    • 必须在类的说明中说明友元函数,说明时以关键字friend开头,后跟友元函数的函数原型,友元函数的说明可以出现在类的任何地方,包括private和public部分。

      • 友元不是类的成员,不受类的声明区域public、private和protected的影响
    #include<iostream>
    
    using namespace std;
    
    class A {
    public:
        A(int val) :a(val) {}
        void fun() {
            cout << a << endl;  //10
            cout << this->a << endl;  //10,等价于cout << a << endl;
        }
    private:
        friend void fun1(const A& res);
    private:
        int a;
    };
    
    void fun1(const A& res) {
        cout << res.a << endl;  //10
    }
    
    int main(int argc, char* argv[]) {
        A res(10);
        res.fun();
        fun1(res);
        getchar();
        return 0;
    }
    • 友元函数不是类的成员函数,所以友元函数的实现与普通函数一样。在实现时不用“::”指示属于哪个类,只有成员函数才使用“::”作用域符号。

    • 友元函数不能直接访问类的成员,只能访问对象成员

      • 我们试想一下,定义友元的目的是在不破坏隐藏(类的数据成员是private)的前提下,定义一个非成员函数访问私有数据成员。类的成员函数能“cout<< a<< endl;”的原因是有this指针。既然是私有数据成员,若要直接访问类的成员,且类的非静态成员必须与特定对象相对,所以必须通过类的对象访问类的私有数据成员
    • 友元函数可以访问对象的私有成员,但普通函数不行。

    • 调用友元函数时,在实际参数中需要指出要访问的对象

    • 类与类之间的友元关系不能被继承。(友元不属于类的成员函数)

    • 友元一般定义在类的外部,但需要在类体内进行声明,为了与该类的成员函数加以区分,在说明时前面加以关键字friend。友元函数不是成员函数,但它可以访问类的私有成员。友元的作用在于提高程序的运行效率,但它破坏了类的封装性和隐藏性,使得非成员函数可以访问类的私有成员

      • 对某些成员函数多次调用时,由于参数传递,类型检查和安全性检查等都需要时间开销,从而影响了程序的运行效率。
    展开全文
  • 友元又分为:友元函数和友元类。 目录1.友元函数1.1 如何对`<< 和 >>`进行重载呢?2.友元类 1.友元函数 友元函数可访问类中的所有成员,但不是该类中的成员函数。 例: class Date { friend void Print...
  • 一、友元函数 1.非成员函数 2.成员函数 3.友元函数的重载 二、友元类 三、友元与封装性 私有成员只能在类的成员函数内部访问,如果想在别处访问对象的私有成员,只能通过类提供的接口(成员函数)间接地进行。...
  • [C++] 友元

    2019-01-07 14:00:58
    友元是一种定义在类外部的普通函数或类,但它需要在类体内进行说明,为了与该类的成员函数加以区别,在说明时前面加以关键字friend。友元不是成员函数,但是它可以访问类中的私有成员。(百度百科) 一、友元函数 ...
  • 友元的理解

    2020-10-24 17:30:40
    C++友元友元函数友元类   我们知道,一个类中可以有公用的(public)成员和私有的(private)成员,在一个家庭的住宅中,我们可以将客厅比喻为公用部分,因为通常客厅是允许任何来访客人进入的,而卧室则不希望...
  • 【C++基础之十】友元函数和友元

    万次阅读 多人点赞 2013-09-18 11:40:06
    友元提供了一种 普通函数或者类成员函数 访问另一个类中的私有或保护成员 的机制。也就是说有两种形式的友元: (1)友元函数:普通函数对一个访问某个类中的私有或保护成员。 (2)友元类:类A中的成员函数访问类B...
  • c++友元函数一些见解 1、为什么要引入友元函数:在实现类之间数据共享时,减少系统开销,提高效率 具体来说:为了使其他类的成员函数直接访问该类的私有变量 即:允许外面的类或函数去访问类的私有变量和保护变量,...
  • 一、友元函数介绍  一般情况下,非类成员函数是不能访问成员变量的。但是有时候我们为了提高程序运行效率,希望外部函数能直接访问类的成员变量。此时我们可以使用友元友元是一种允许非类成员函数访问类的非公有...
1 2 3 4 5 ... 20
收藏数 40,306
精华内容 16,122
关键字:

友元