精华内容
下载资源
问答
  • 当声明了友元函数或者友元类之后,该函数或者类可以访问类的所有成员,包括private成员,当然访问过程需要通过类的对象进行。例如声明一个友元函数,有两种情况: ①该函数是普通全局函数 一般情况下,使用一个...

    友元声明

    前面加上关键字friend,该声明可以放在任何一个地方,一般放在类的定义中。当声明了友元函数或者友元类之后,该函数或者类可以访问类的所有成员,包括private成员,当然访问过程需要通过类的对象进行。例如声明一个友元函数/类,有三种情况:
    ①友元是普通的全局函数
    一般情况下,使用一个函数需要先声明,或者定义在前,但是声明一个全局函数为友元函数的时候,可以理解为只是声明,而非调用,因此不用先在类的前面声明该全局函数。另外,如果要在类的前面声明该友元函数,需要用到类,因此还得在该声明的前面声明类的定义,比较麻烦。故总结顺序如下:类的定义,类中友元函数声明,类后友元函数实现。 这样的顺序应该万无一失了。

    #include<iostream>
    using namespace std;
    
    class student{
    	friend func(student *stu);//声明全局函数func为友元函数,不用在类前面声明,定义在后面。
    	private:
    		int age;
    //		void set_age(int t_age):age(t_age){};//不能使用初始化列表
    		void set_age(int t_age)
    		{
    			age = t_age;
    		 } 
    	public:
    		student(int t_age):age(t_age){};
    		void show_age(){cout<<"age = "<<age<<endl;};
    }; 
    void func(student *stu){
    	stu->set_age(-1); //可以通过对象访问private成员 
    	stu->show_age(); //当然也可以访问public成员
    }
    int main()
    {
    	student* stu = new student(10);
    	func(stu); //结果为: age = -1;
    	//查看age是否被修改
    	stu->show_age(); //结果为-1
    	//注意不能直接输出cout<<stu->age<<endl;
    	return 0;
    }
    

    这里刚开始的时候出了一个问题,set_age函数我使用了初始化列表,然后报错,搜查之后发现错误原因在于初始化列表的使用,注意:只有构造函数初始化的时候能使用初始化列表
    这里又发现了一个新的问题,在经过func函数之后,我想查看stu中的private成员age是否发生了变化,于是我试图通过直接输出age:

    cout << stu->age << endl;
    

    但是发现不可以,难道对象自己不能直接访问自己的私有数据成员么?
    查阅资料之后发现解释如下,private,public是针对类外的对象,类外的其他类对象的,这里stu定义在类外,因此不能访问私有数据成员。但是有一个例外,那就是友元函数,友元函数可以直接访问。而定义在类内的成员函数可以直接访问。总结一句话就是:在类内定义,可以访问,在类外定义,不能访问,友元函数可以访问
    ②友元是一个类
    同友元是一个函数一样,友元类可以先不定义,在当前类中声明友元类不会报错。所以顺序应该为:当前类的定义,类中声明友元类,友元类定义
    当然,如果先定义友元类,那么在友元类之前需要声明当前类。

    #include<iostream>
    using namespace std;
    
    class student {
    	friend class teacher; //声明一个友元类
    	//该友元类teacher还没有声明/定义,不会报错。
    private:
    	int age;
    	void set_age(int t_age);
    public:
    	student(int t_age) :age(t_age) {};
    	void show_age();
    };
    //友元类的实现
    class teacher {
    public:
    	teacher() {};
    	void func(student *stu); //如果把友元类定义在前,那么需要先声明student类,否则报错
    };
    void teacher::func(student* stu)
    {
    	stu->set_age(-1);
    	stu->show_age();
    }
    void student::set_age(int t_age)
    {
    	age = t_age;
    }
    void student::show_age()
    {
    	cout<<"age = "<<age<<endl;
    }
    int main()
    {
    	teacher* tea = new teacher();
    	student* stu = new student(10);
    	tea->func(stu); //age = -1
    	return 0;
    }
    

    ③友元是类中的一个成员函数
    这里需要注意的是:被声明为友元函数的成员函数必须定义在该类的前面,也就是这个成员函数所属的类在该类的前面定义,里面的成员函数可以只是先声明。也就是友元函数的类定义要在前面定义。但是问题来了,友元函数中的参数类型是当前类,所以得提前声明当前类。因此顺序为:当前类声明,友元类定义,当前类定义,两个类各种函数的具体实现。

    #include<iostream>
    using namespace std;
    class student; //必须提前声明,因为友元类中的函数要用到
    //友元函数所属类的定义必须在前,具体函数实现可以最后考虑
    class teacher {
    public:
    	teacher() {};
    	void func(student* stu); //友元函数
    };
    
    class student {
    	friend void teacher::func(student *stu); //声明一个类中的成员函数为友元函数
    private:
    	int age;
    	void set_age(int t_age);
    public:
    	student(int t_age) :age(t_age) {};
    	void show_age();
    };
    //两个类中的成员函数实现
    void teacher::func(student* stu)
    {
    	stu->set_age(-1);
    	stu->show_age();
    }
    void student::set_age(int t_age)
    {
    	age = t_age;
    }
    void student::show_age()
    {
    	cout<<"age = "<<age<<endl;
    }
    int main()
    {
    	student* stu = new student(10);
    	teacher* tea = new teacher();
    	tea->func(stu); //teacher类中的成员函数func被student类声明为友元函数,该函数可以访问student类所定义的对象的private成员
    
    	return 0;
    }
    
    

    最后需要注意两点:
    派生类中的友元函数对其基类不起作用,不能访问基类的private成员
    只有当某个类中的成员函数的定义都完整给出之后才能定义该类的对象。可以理解为,定义还没完成,无法确定存储空间大小,也就无法生成一个对象。

    展开全文
  • 友元函数定义后可以访问的所有对象的所有成员,包括private、protected、public成员友元函数使用前必须要在定义声明,声明在其函数名前加上关键字friend。该声明可以放在公有成员中,也可以放在私有成员...

    在C++中,为了使类的私有成员和保护成员能被其它类或其它成员函数访问,引入的友元的概念。

    友元函数

    友元函数定义后可以访问改类的所有对象的所有成员,包括private、protected、public成员。友元函数使用前必须要在类定义时声明,声明时在其函数名前加上关键字friend。该声明可以放在公有成员中,也可以放在私有成员中。友元函数可以在类内部定义,也可以在类外部定义,通常在类外部定义。使用友元函数注意事项:

    1.友元函数不是成员函数,定义时不必加::。

    2.友元函数不是类的成员,因而不真直接引用对象的名字,也不能通过this指针引用对象的成员,必须通过作为入口参数传递进来的对象名或对象指针来引用该对象的成员。因些,友元函数一般都带有一个该函数的入口参数,如下例中的area(Rec &rec)。

    3.当一个函数需要访问多个类时,应该把这个函数同时定义为为些类的友元函数。

    友元函数声明:  friend<数据类型><友元函数名>(参数表);

    #include<iostream>
    using namespace std;
    class Rec{
          double len,wid;//私有成员 
          public:
                 Rec(double a=0,double b=0);
                 Rec(Rec &r);
                 friend double area(Rec &rec);//声明友元函数 
                 };
    Rec::Rec(double a,double b)
    {
                    len=a ;
                    wid=b;
                    }
    double area(Rec &rec)
    {
           return rec.len*rec.wid;//友元访问私有成员 
           }
    int main()
    {
        Rec r1(3,4);
        cout<<area(r1)<<endl;
        system("pause");
        }
    

    友元成员

    如果一个类的成员函数是另一个类的友元函数,则称这个成员函数为友元成员。通过友元成员,不仅可以访问自己所在的类对象中的所有其他成员,还可以访问由关键字friend声明语句所在的类的对象中的所有成员。这种机制可以让两个类相互访问,从而共同完成某些特定任务。例:

    #include<iostream>
    #include<string>
    using namespace std;
    class boy;//声明boy类
    class girl
    {
          char *name;
          int age;
          public:
                 girl(char *n,int a)
                 {
                   name = new char[strlen(n)+1];
                   strcpy(name,n);
                   age = a;
                           }
                 void prt(boy &b);
                 ~girl()
                 {
                        delete name;
                        }  
          }; 
    
    class boy{
          char *name;
          int age;
          public:
                 boy(char *n,int a)
                 {
                   name = new char[strlen(n)+1];
                   strcpy(name,n);
                   age = a;
                          }
          friend void girl::prt(boy &b);  //声明友元成员。在声明友元函数时,要加上成员函数所在类的类名和作用域运算符::。
          ~boy()
          {
                delete name;
                }       
          };
    
    void girl::prt(boy &b)//定义友元成员。  这里不能直接放在girl类后面,否则会报错。 
    {
         cout<<"girl\'s name: "<<name<<"  age:"<<age<<endl;
         cout<<"boy\'s name: "<<b.name<<"  age:"<<b.age<<endl;
         }      
    int main()
    {
        girl g1("Hanmeimei",15);
        boy b1("Lilei",16);
        g1.prt(b1);
        system("pause");
        } 

    注意:

    1.当一个类的成员函数作为另一个类的友元函数时,必须先定义成员函数所在的类,如上述代码中的girl的成员函数prt()为类boy的友元函数,就必须先定义类girl,并且ptr要在boy之后定义。

    2.在声明友元函数时,要加上成员函数所在类的类名和作用域运算符::。

    友元类

    如果一个类作为另一个类的友元,称这个类为友元类。当一个类成为另一个类的友元类时,这个类的所有成员函数都成为另一个类的友元函数。友元类中的所有成员函数都可以通过对象名直接访问另一个类的所有成员,从而实现不同类之间的数据共享。

     #include<iostream>
    #include<string>
    using namespace std;
    class boy;//声明boy类
    class girl
    {
          char *name;
          int age;
          public:
                 girl(char *n,int a)
                 {
                   name = new char[strlen(n)+1];
                   strcpy(name,n);
                   age = a;
                           }
                 void prt(boy &b);
                 ~girl()
                 {
                        delete name;
                        }  
          }; 
    
    class boy{
          char *name;
          int age;
          public:
                 boy(char *n,int a)
                 {
                   name = new char[strlen(n)+1];
                   strcpy(name,n);
                   age = a;
                          }
          friend class girl;  //声明友元成员,加上成员函数所在的类名和::
          ~boy()
          {
                delete name;
                }       
          };
    
    void girl::prt(boy &b)//定义友元成员。  这里不能直接放在girl类后面,否则会报错。 
    {
         cout<<"girl\'s name: "<<name<<"  age:"<<age<<endl;
         cout<<"boy\'s name: "<<b.name<<"  age:"<<b.age<<endl;
         }      
    int main()
    {
        girl g1("Hanmeimei",15);
        boy b1("Lilei",16);
        g1.prt(b1);
        system("pause");
        } 
    


    boy类的定义中,将girl类声明为boy类的友元类,因此,girl类的成员可以访问boy类的所有成员。

    注意:

    1.友元关系是不能传递的。类B是类A的友元,类C是类B的友元,但类C与类A无关系。

    2.友元关系也是单向的。类B是类A的友元,类B的成员函数可以访问类A的所有成员,但是类A不可以访问类B的private和protected成员。

    展开全文
  • 友元分为友元函数、友元成员和友元类三...由于友元函数不是类的成员,所以没有this指针,访问对象成员时,必须使用对象名。 虽然友元函数是在中说明的,但其名字的作用域在外,作用域的开始点在说明点,作用

    友元分为友元函数、友元成员和友元类三种,友元声明可以放在类的公有、私有或保护,结果都一样的。

    一.友元函数

    友元函数是一种说明在类定义体内的非成员函数。说明友元函数的方法如下:
    friend 返回值类型 函数名(参数表)
    说明:

    1. 友元函数是在类中说明的一个函数,不是该类的成员函数,但允许访问该类的所有成员。它是独立于任何类的一般外界函数。
    2. 由于友元函数不是类的成员,所以没有this指针,访问该类的对象成员时,必须使用对象名。
    3. 虽然友元函数是在类中说明的,但其名字的作用域在类外,作用域的开始点在说明点,作用域的结束点和类名相同。
    4. 在类外定义友元函数时,去点friend关键字。

    二.友元成员

    另一个类的成员函数可以作为某个类的友元,只是在声明友元函数时要加上成员函数所在的类名,称为友元成员。
    声明如下:
    friend 类名::成员函数名(形参列表)

    三.友元类

    某一个类可以是另一个类的友元,这样作为友元类中的所有成员函数都可以访问另一个类中的私有成员。
    说明方式如下:
    friend class 类名;

    例题

    设计一个JX类表示矩形,矩形的长和宽作为其两个数据成员。编写一个求矩形面积的函数area(),并将它声明为JX的一个友元函数。利用area()求出该矩形的面积。
    运行结果如下:

    在这里插入图片描述
    代码如下:

    #include<iostream>
    using namespace std;
    class JX
    {
    friend int area(JX j);
    public:
    JX(int a,int b)
    {
    this->x=a;
    this->y=b;
    }
    void print()
    {
    cout<<"length:"<<this->x<<endl;
    cout<<"width:"<<this->y<<endl;
    }
    int x,y;
    };
    int area(JX j)
    {
    int a,b;
    a=j.x;
    b=j.y;
    return a*b;
    }
    int main()
    {
    JX j(12,5);
    j.print();
    int i;
    i=area(j);
    cout<<"area:"<<i<<endl;
    return 0;
    }
    展开全文
  • 友元函数与友元类

    2017-08-31 12:11:49
    面向对象编程一个重要思想就是实现数据隐藏(类的封装特性),即:非成员函数不能访问private 或者 protected 变量。有些时候我们需要不经成员函数而访问private 或者 protected数据,那就需要用到 友元函数 或者...

    面向对象编程的一个重要思想就是实现数据隐藏(类的封装特性),即:非成员函数不能访问private 或者 protected 变量。

    有些时候我们需要不经成员函数而访问private 或者 protected数据,那就需要用到 友元函数 或者友元类。

    1. 友元函数

    使用 friend 关键字在类内任意位置声明函数为友元函数。 而且,当要访问
    非static成员时,需要对象作为参数。

    如下:

    #include <iostream>
    using namespace std;
    
    class Distance
    {
        private:
            int meter;
        public:
            Distance(): meter(0) { }
    
        private:
            // 可以在任意位置声明友元函数,对象作为参数
            friend int addFive(Distance);
    };
    
    int addFive(Distance d)
    {
        d.meter += 5;
        return d.meter;
    }
    
    int main()
    {
        Distance D;
        cout<<"Distance: "<< addFive(D);
        return 0;
    }
    \\ output
    Distance: 5

    上面的例子只是举例友元函数的用法,其实没什么意义。 友元函数在操作两个不同类的对象时才体现出它的价值。

    如下面的例子:

    #include <iostream>
    using namespace std;
    
    // 提前声明类B
    class B;
    class A {
        private:
          int numA;
        public:
          A(): numA(12) { }
          // 声明友元函数
          friend int add(A, B);
    };
    
    class B {
        private:
           int numB;
        public:
           B(): numB(1) { }
           // 声明友元函数
           friend int add(A , B);
    };
    
    // 两个不同类的私有变量相加
    int add(A objectA, B objectB)
    {
       return (objectA.numA + objectB.numB);
    }
    
    int main()
    {
        A objectA;
        B objectB;
        cout<<"Sum: "<< add(objectA, objectB);
        return 0;
    }

    2 友元类

    当一个类成为友元类时,其所有成员函数自动成为友元函数,如下例。 B中的所有函数都是A的友元函数,因此B中函数可以访问A的private 或者 protected数据。

    ... .. ...
    class B;
    class A
    {
       // class B is a friend class of class A
       friend class B;
       ... .. ...
    }
    
    class B
    {
       ... .. ...
    }

    3 友元的注意事项

    • (1)应慎用友元。 因为其会破坏面向对象的封装特性,造成一定的安全问题。
    • (2)友元不是相互的。 类A是B的友元,但B不会自动变成A的友元
    • (3)友元是不可继承的。
    • (4)普通成员函数有this指针,static和友元函数没有。

    参考资料

    展开全文
  • A希望B能够访问到自己私有成员,所以设置B为其友元类, B类在实例化,需要用到A类对象进行初始化(构造函数用到A类对象指针)。 涉及到了头文件相互包含问题,头文件中对所需类类型进行前向声明...
  • 友元的作用是提高程序运行效率,它可以直接访问类的私有和保护成员,但也因此破坏了类封装性,应谨慎使用。 表现形式: 友元可以是一个函数,也可以是一个类。前者是友元函数,后者是友元类。 2.1 友元函数:...
  • C++中的友元类

    2020-07-25 21:34:36
    友元类:在类A中,将类B声明为一个友元类,在类B中就可以访问类A私有成员数据和成员方法了。友元是一种定义在类外部普通函数和类,但是它需要在类体内进行说明,在使用时需要加关键字friend。 代码实现 # ...
  • 友元函数和友元类

    2018-12-03 22:51:00
     友元函数的目的是,让函数对象类型的参数可以直接访问对象的私有成员!避免了出现不断调用该函数通过get函数获取私有成员引起的压栈出栈问题!  在需要定义为友元函数的函数前加friend关键字,且在需要直接...
  • C++之友元函数和友元类

    千次阅读 2015-03-04 20:00:31
    在介绍类和对象时,已经说过类具有封装性,类中的私有成员一般只有通过该类中的成员函数才可以访问,而程序中的其他函数无法直接访问类中的私有成员的。如果在一定的条件下需要访问类的私有成员,就必须通过对象来...
  • 2.0 友元函数和友元类必须在中声明,然后,定义对象,就可以实现对原私有数据成员的访问! 3.0 在public中声明; 4.0 既然在中声明了,所以在书写友元函数定义,不需要再加作用域运算符。 1.0 注意: ...
  • 一、前言本部分为C++语言刷题系列中第4节,主要讲解这几个知识点:友元函数和友元类。...知识点1:友元函数· 类外普通函数想要访问类的私有成员时,可以通过使用friend关键字来声明其为类...
  • c++学习之类的友元

    2017-10-19 16:16:52
    1.友元函数 C++语法:在类中声明友元函数 class 类名 // 类声明部分{ ...... friend 友元函数原型声明 ; } ;语法说明:  在类声明部分声明友元函数原型,声明... 友元函数可以在其函数体内访问类对象
  • C++-使用类友元

    2018-07-05 22:25:03
    使用类 (2) 友元 ...通过让函数成为友元,可以赋予该函数与类的成员函数相同的访问权限。 1. 创建友元 创建友元函数的第一步将其原型放在声明中,并在原型声明前加上关键字friend: f...
  • 15、C++类的友元

    2013-04-28 10:24:28
    C++中的友元 作用:使用友元可以使非成员函数通过形参对象,直接访问对象或者...友元函数可以访问类的私有成员,但是它并不是成员函数,所以不能直接访问对象的 数据成员,也不能通过this指针访问对象的数据成员,,
  • 此时将非成员函数定义为类的友元函数便可直接访问类的私有或保护数据成员使用友元函数目的是提高程序执行效率,但友元函数破坏了类信息隐蔽性,慎用。 类的友元函数定义在类外部,但有权访问类的所有...
  • C++ 模板友元

    千次阅读 2018-08-15 11:07:38
    模板类的友元分三: ...count()函数不是通过对象调用(它是友元不是成员函数),也没有对象参数,那么它如何访问hasfriend对象? 它可以访问全局对象;可以使用全局指针访问非全局对象;可以创建自己...
  • 友元函数

    2021-01-31 13:48:52
    友元函数不能使用对象的this指针,访问成员分情况: 1、要访问非static成员时,需要对象做参数。 2、要访问static成员或全局变量时,则不需要对象做参数。 友元的关系是单向的而不是双向的。如果声明...
  • 然后在体外对友元函数进行定义,定义的格式和普通函数相同,但可以通过对象作为参数直接访问对象的私有成员 说明如下 1)必须在的说明中说明友元函数,说明以关键字friend开头,后跟友元函数的函数原型,...
  • 静态成员友元

    2019-09-25 17:49:48
    1、的所有对象往往需要共享某个数据,所以需要静态成员,如学生中的学生总数 ...4、当使用对象来调用静态变量,c++只关心对象的类型 5、静态成员函数与联系,不与的对象联系,所以访问静态成员函数...
  • 友元函数简单说明

    2020-12-21 15:46:47
    首先友元函数为了方便一个...在此函数中可以通过形参myClass类对象或指针,引用来访问类myClass的成员变量,这里对于任何访问权限的成员变量都可以访问。 还可以使用另一种方式,用一个类的成员函数作为另一个类的友元
  • 友元函数使用说明 ...3)友元函数不能直接访问类的成员,只能访问对象成员, 4)友元函数可以访问对象的私有成员,但普通函数不行; 5)调用友元函数,在实际参数中需要指出要访问的对象, 6)类与类之间的
  • 友元函数说明

    2007-12-19 20:37:00
    友元函数说明如下: 1)必须在类的说明中说明友元函数,说明以关键字friend开头,后跟友元函数的函数原型,友元函数的说明可以出现在类的任何地方,包括在... 3)友元函数不能直接访问类的成员,只能访问对象成员, 4)友元函数
  • 对于友元函数的几点说明: 1)必须在类的说明中说明友元函数,说明以关键字friend开头,后跟友元函数的函数原型,友元函数的说明可以在类的任何地方...3)友元函数不能直接访问类的成员,只能访问对象成员; 4)...
  • c++中的友元函数

    2009-09-03 09:20:00
    友元函数 1)必须在类的说明中说明友元函数,说明以关键字friend开头,后跟友元函数的函数原型,友元函数的说明可以出现在类的任何地方,包括在private和public部分;... 3)友元函数不能直接访问类的成员,只能访问对象成员
  • 答:因为重载为成员函数在调用是有this指针的,且this只能指向该对象,而输入输出流的使用对象只能是cout或者cin,所以不能重载为所需类的成员函数。 倒是可以重载为ostream的成员函数,但是源码没法改变,...
  • 友元函数几点注意事项和实例

    千次阅读 2014-03-09 09:12:00
    友元函数说明如下 :  1)必须在类的说明中说明友元函数,说明以关键字friend开头,后跟友元函数的函数原型,友元函数的说明可以出现在类的任何地方,包括在...3)友元函数不能直接访问类的成员,只能访问对象成员
  • C++友元

    2013-08-06 16:35:44
    如果类A中的函数要访问类B中的成员(例如:智能指针类的实现),那么类A中该函数要是类B的友元函数。具体来说:为了 使其他类的成员函数直接访问该类的私有变量。在别的类中声明友元,共享自己即:允许外面的类或...
  • 4.7 友元

    2016-06-13 08:51:05
    在面向对象的程序设计中,的封装性使得我们使用类(对象)的成员数据经常要通过(对象)的成员函数。这对于是一种保护。但在某些情况下,频繁的成员函数调用使得效率严重受损。 例如,定义矩阵,并有两...

空空如也

空空如也

1 2 3 4 5 ... 7
收藏数 136
精华内容 54
关键字:

友元访问类对象的成员时使用