zoukankan      html  css  js  c++  java
  • C++ friend 用法汇总

    C++这位朋友同意之类的非公共成员的机制是一个类或函数访问,根据朋友的类型分为三种类型:一般非类成员函数为好友,类成员函数为好友。类为好友。

    1 内容朋友

    包括报表朋友的朋友以及朋友的定义。明默的感觉到声音的朋友extern,的作用域已经扩展到了包括该类定义的作用域。所以即便我们在类的内部定义友元函数也是没有关系的。

    2 普通的非成员函数友元

    这类友元函数一般是操作符。比如输入输出操作符.示比例如以下所看到的:
    //OpeClass.h
    #pragma once
    class OpeClass
    {
    	friend int func(const OpeClass xx);
    public:
    	OpeClass(void);
    	OpeClass(int x,int y);
    	~OpeClass(void);
    private:
    	int width;
    	int height;
    };
    //OpeClass.cpp
    #include "OpeClass.h"
    
    
    OpeClass::OpeClass(void)
    {
    	width = 50;
    	height = 50;
    }
    
    
    OpeClass::OpeClass(int x,int y):width(x),height(y)
    {
    }
    
    
    OpeClass::~OpeClass(void)
    {
    }
    
    
    int func(const OpeClass xx)
    {
    	return xx.height * xx.width;
    }
    


    //main.cpp
    #include "OpeClass.h"
    #include <iostream>
    using namespace std;
    
    
    void main()
    {
    	OpeClass XO;
    	cout<<func(XO);
    	system("pause");
    }

    3 类作为友元

    类作为友元须要注意的是友元类和原始类之间的相互依赖关系,假设在友元类中定义的函数使用到了原始类的私有变量。那么就须要在友元类定义的文件里包括原始类定义的头文件。
    可是在原始类的定义中(包括友元类声明的那个类),就不须要包括友元类的头文件。也不须要在类定义前去声明友元类,由于友元类的声明自身就是一种声明(它指明能够在类外找到友元类),演示样例程序例如以下所看到的:
    //A.h
    #pragma once
    #include <iostream>
    using namespace std;
    class A
    {
    	friend class B;
    public:
    	~A(void);
    	static void func()
    	{
    		cout<<"This is in A"<<endl;
    	}
    private:
    	A(){};
    	static const A Test;
    };
    

    //A.cpp
    #include "A.h"
    const A A::Test = A();
    A::~A(void)
    {
    }

    //B.h
    #pragma once
    #include "C.h"
    class B
    {
    public:
    	B(void);
    	~B(void);
    	void func(C& c);
    };

    //B.cpp
    #include "B.h"
    #include "A.h"
    #include "C.h"
    #include <iostream>
    using namespace std;
    
    
    B::B(void)
    {
    }
    
    
    
    
    B::~B(void)
    {
    }
    
    
    void B::func(C& c)
    {
    	cout<<"This is in B"<<endl;
    	A::Test.func();
    	c.func(A::Test);
    }
    

    //C.h
    #pragma once
    class A;
    class C
    {
    public:
    	C(void);
    	~C(void);
    	void func(const A& a);
    };

    //C.cpp
    #include "C.h"
    #include <iostream>
    using namespace std;
    
    C::C(void)
    {
    }
    
    C::~C(void)
    {
    }
    
    void C::func(const A& a)
    {
    	cout<<"This is in C"<<endl;
    }

    //main.cpp
    #include "A.h"
    #include "B.h"
    #include "C.h"
    #include <iostream>
    using namespace std;
    
    void main()
    {
    	B b;
    	C c;
    	b.func(c);
    	system("pause");
    }

    4 类成员函数作为友元函数

    这个略微有点复杂,由于你要类成员函数作为友元,你在声明友元的时候要用类限定符,所以必须先定义包括友元函数的类,可是在定义友元的函数时候。又必须事先定义原始类。通常的做法先定义包括友元函数的类。再定义原始类。这个顺序不能乱。(假设是友元类,则没有这样的这样的必须)如以下所看到的:

    //B.h
    #pragma once
    class A;
    class B
    {
    public:
    	B(void);
    	~B(void);
    	int func(A xx);
    };

    //A.h
    #pragma once
    #include "B.h"
    class A
    {
    friend int B::func(A xx);
    public:
    	A(void):mx(20),my(30){}
    	~A(void){}
    private:
    	int mx;
    	int my;
    };

    //B.cpp
    #include "B.h"
    #include "A.h"
    
    
    B::B(void)
    {
    }
    
    
    B::~B(void)
    {
    }
    
    int B::func(A xx)
    {
    	return xx.mx * xx.my;
    }

    //main.cpp
    #include "A.h"
    #include "B.h"
    #include <iostream>
    using namespace std;
    void main()
    {
    	A a;
    	B b;
    	cout<<b.func(a)<<endl;
    	system("pause");
    }

    5 友元不具有相互性,仅仅具有单项性

    若类B是类A的友元。类A不一定是类B的友元,要看在类中是否有对应的声明。



    6 友元不能被继承

    B是A的友元类。C是B的子类。推不出C是A的友元

    7 友元不具有传递性

    B是A的友元,C是B的友元,推不出C是A的友元

    8 相互为友元的类

    这个事实上没什么好注意的,以下是实例。类A,类B互为友元
    //A.h
    #pragma once
    class A
    {
    friend class B;
    public:
    	A(void);
    	~A(void);
    	int funa(B& b);
    private:
    	int mx;
    	int my;
    };
    

    //A.cpp
    #include "A.h"
    #include "B.h"
    
    
    A::A(void)
    {
    	mx = 10;
    	my = 10;
    }
    
    
    A::~A(void)
    {
    }
    
    
    int A::funa(B& b)
    {
    	return b.mb * b.mc;
    }

    //B.h
    #pragma once
    class B
    {
    	friend class A;
    public:
    	B(void);
    	~B(void);
    	int funb(A& a);
    private:
    	int mb;
    	int mc;
    };

    //B.cpp
    #include "B.h"
    #include "A.h"
    
    
    B::B(void)
    {
    	mb = 20;
    	mc = 20;
    }
    
    B::~B(void)
    {
    }
    
    int B::funb(A& a)
    {
    	return a.mx *a.my;
    }
    

    //main.cpp
    #include "A.h"
    #include "B.h"
    #include <iostream>
    using namespace std;
    void main()
    {
    	A a;
    	B b;
    	cout<<a.funa(b)<<endl;
    	cout<<b.funb(a)<<endl;
    	system("pause");
    }

    9 假设想要指定两个类都有成员函数作为对方的友元,那么必须第2个类是第一个类的友元

    //A.h
    #pragma once
    
    // class B is a friend class of A
    class A
    {
    	friend class B;
    public:
    	A(void):ma(10),mb(20){}
    	~A(void){}
    	int funa(B& b);
    private:
    	int	ma;
    	int	mb;
    };

    //B.h
    #pragma once
    #include "A.h"
    
    
    // A's function funa is a friend function of B
    class B
    {
    	friend int A::funa(B& b);
    public:
    	B(void);
    	~B(void);
    	int funb(A& a);
    	int func(A& a);
    private:
    	int mx;
    	int my;
    };
    

    //A.cpp
    #include "A.h"
    #include "B.h"
    
    
    int A::funa(B& b)
    {
    	return  b.mx * b.my;
    }

    //B.cpp
    #include "B.h"
    
    B::B(void):mx(12),my(15)
    {
    }
    
    
    B::~B(void)
    {
    }
    
    
    int B::funb(A& a)
    {
    	return a.ma + a.mb;
    }
    
    int B::func(A& a)
    {
    	return a.ma * a.mb;
    }

    //main.cpp
    #include "A.h"
    #include "B.h"
    #include <iostream>
    using namespace std;
    void main()
    {
    	A a;
    	B b;
    	cout<<a.funa(b)<<endl;
    	cout<<b.funb(a)<<endl;
    	cout<<b.func(a)<<endl;
    }


    版权声明:本文博主原创文章。博客,未经同意不得转载。

  • 相关阅读:
    ADHOC Report 配置
    html tags
    Stingray验证机制
    常用jQuery知识
    Communication API
    stingray前端架构总体设计及运行过程
    REP report开发技巧
    WorkFlow业务介绍
    MySQL auto_increment初始值设置
    SQL Server中order by的使用,我们来填坑
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/4914171.html
Copyright © 2011-2022 走看看