zoukankan      html  css  js  c++  java
  • C++友元

    友元

    只有本类中的成员函数可以访问本类的私有成员,阻止其他访问,但在某些情况下。我们要访类的私有成员,如果把私有成员定义为共有的话,就破坏了类的隐藏性,这是我们就用到了友元。

    友元(friend)机制可以允许类外的函数和其他类访问本类的私有成员。

    友元在类中声明,以关键字firend开始,可以在类中任意位置声明。友元函数虽然定义在类内,但其并不是类成员,所以其不受publicprotectedprivate的影响.

    友元函数

    将非成员函数声明为友元函数

    友元函数是不在类中的函数,但是可以访问类内的所有成员的函数。

    #include <bits/stdc++.h>
    using namespace std;
    class A {
    	private :
    		int x;
    		friend void query_pri(A a);	//在private里定义的友元函数 
    		
    	public :
    		friend void query_pub(A a);	//在public里定义的友元函数 
    		
    		A(int a = 0) : x(a) {}
    	protected :
    		friend void query_pro(A a);	//在protected里定义的友元函数 
    		
    };
    
    //注意,三个query函数不是类成员函数
    
    void query_pri(A a) {
    	printf("%d
    ", a.x);
    }
    
    void query_pro(A a) {
    	printf("%d
    ", a.x);
    }
    
    void query_pub(A a) {
    	printf("%d
    ", a.x);
    }
    
    int main() {
    	A a(10);
    	query_pub(a);
    	query_pro(a);
    	query_pri(a);
    	//三个函数都可以执行,说明友元函数不受在类中定义位置的影响
    	
    	//说明友元函数不是类成员函数 
    	 
    	return 0;
    }
    

    注意:友元函数不同于类的成员函数,在友元函数中不能直接访问类的成员,必须要通过对象访问。

    例如,我们把query_pub函数改为这样

    void query_pub() {
    	printf("%d
    ", x);
    }
    

    就会报错。

    之前提到过,成员函数会自动隐式的增加this指针,来访问对象的成员,但三个query函数不是类成员函数,没有this指针,这样编译器就不知道使用哪个对象,所以必须通过参数传递对象,并在访问时说明对象。

    将其他类的成员函数声明成友元函数

    友元函数不仅可以使非成员函数,也可以是另一个类的成员函数。

    #include <bits/stdc++.h>
    using namespace std;
    
    class B;    //注意这里
    
    class A {
    	public :
    		void query(B oth);
    };
    
    class B {
    	private :
    		int b;
    	public :
    		B(int x) : b(x) {}
    		friend void A::query(B oth);
    };
    
    void A::query(B oth) {
    	printf("%d", oth.b);
    }
    
    int main() {
    	B b(10);
    	A a;
    	a.query(b);
    	return 0;
    }
    

    输出:

    10
    

    这段代码里注意两点

    1. 程序中对B类提前进行了声明,因为在B类定义之前就用到了它,就像如果要使用一个变量时要提前声明一样。
    2. query函数的声明和实现被分开,把query放在了B类的后面,因为在query中用到了B中的成员,若不提前声明B,就不能确定B类中是否拥有该成员,就会报错。

    一个函数可以被多个类声明为友元函数,可以访问多个类的privateprotected成员。

    友元类

    类也可以被声明为友元,友元类的所有成员函数都是另一个类的友元函数,可以访问另一个类中的protectedprivate成员。

    格式:

    friend class class_name
    

    如将B声明为A的友元,那B中的所有成员函数都是类A的友元函数,可以访问A中的所有成员。
    如:

    #include <bits/stdc++.h>
    using namespace std;
    
    class A {
    	private :
    		int x, y;
    	public :
    		friend class B;
    		A(int a = 10, int b = -20) : x(a), y(b) {};
    };
    
    class B {
    	public:	
    		void print(A a) {
    			printf("%d
    ", a.x);
    		}
    		void print_abs(A a) {
    			printf("%d
    ", abs(a.y));
    		}
    };
    
    int main() {
    	A a;
    	B b;
    	b.print(a), b.print_abs(a);
    	return 0;
    }
    

    使用友元类时注意:

    • 友元关系不能被继承。
    • 友元关系是单向的,不具有交换性。若类B是类A的友元,类A不一定是类B的友元,要看在类中是否有相应的声明。
    • 友元关系不具有传递性。若类B是类A的友元,类C是B的友元,类C不一定是类A的友元,同样要看类中是否有相应的声明
  • 相关阅读:
    JMeter中的HTTPS套接字错误
    使用JMETER进行REST API测试(分步指南)
    JMeter BeanShell示例
    未能载入软件包“WebDriverAgentRunner”,因为它已损坏或丢失必要的资源。
    ERROR: Could not connect to lockdownd, error code -19 -20
    (转)Selenium-11: Execute JavaScript with JavascriptExecutor
    在服务器上使用 gradle 打包 android 源码
    poi+properties文件实现多环境测试数据一键切换
    cocos2D-X 常用功能封装
    MD5 AND JSON AND XML
  • 原文地址:https://www.cnblogs.com/lykkk/p/10779421.html
Copyright © 2011-2022 走看看