# C++中的friend函数详细解析（一）

https://www.jb51.net/article/96567.htm

C++中的友元机制允许类的非公有成员被一个类或者函数访问，友元按类型分为三种：普通非类成员函数作为友元,类的成员函数作为友元，类作为友元。友元包括友元的声明以及友元的定义。友元的声明默认为了extern，就是说友元类或者友元函数的作用域已经扩展到了包含该类定义的作用域，所以即便我们在类的内部定义友元函数也是没有关系的。

1.1.普通的非成员函数友元

#include "cmath"
#include "iostream"
using namespace std;
class Point
{
public:
Point(double xx,double yy)
{
x=xx;
y=yy;
}
void GetXY();
friend double Distance(Point &a,Point &b);
protected:
private:
double x,y;
};
void Point::GetXY()
{
//cout<<"("<<this->x<<","<<this->y<<")"<<endl;
cout<<"("<<x<<","<<y<<")"<<endl;
}
double Distance(Point &a,Point &b)
{
double length;
length=sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));   //它可以引用类中的私有成员
return length;
}
int main(void)
{
Point p1(3.0,4.0),p2(6.0,8.0);
p1.GetXY();  //成员函数的调用方法，通过使用对象来调用
p2.GetXY();
double d = Distance(p1,p2);   //友元函数的调用方法，同普通函数的调用一样，不要像成员函数那样调用
cout<<d<<endl;
system("pause");
return 0;
} 

#include <cmath>
#include <iostream>
using namespace std;
class Point
{
public:
Point(double xx,double yy)
{
x=xx;
y=yy;
}
void GetXY();
friend double Distance(Point &a,Point &b);
friend ostream &operator <<(ostream &a,Point &b);
protected:
private:
double x,y;
};
// friend ostream& operator<<(ostream& o,A& another);
ostream &operator <<(ostream &out,Point &b)  //在类中声明的时候，可以是ostream &a，函数定义的时候也可以是ostream &out
{
out<<"("<<b.x<<","<<b.y<<")"<<endl;
return out;
}
void Point::GetXY()
{
//cout<<"("<<this->x<<","<<this->y<<")"<<endl;
//cout<<"("<<x<<","<<y<<")"<<endl;
cout<<*this;
}
double Distance(Point &a,Point &b)
{
double length;
length=sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
return length;
}
int main(void)
{
Point p1(3.0,4.0),p2(6.0,8.0);
p1.GetXY();
p2.GetXY();
double d = Distance(p1,p2);
cout<<d<<endl;
system("pause");
return 0;

} 

2.类作为友元

//A.h
#pragma once
#include <iostream>
using namespace std;
class A
{
//friend class B; //如果不写这句话将会出现编译错误
public:
~A(void);
A();
private:
int m_nItem;
};
//A.cpp
#include "A.h"

A::A()
{
m_nItem =3;
}

A::~A(void)
{
}
//B.h
#pragma once

class B
{
public:
B(void);
~B(void);
int func();
};
//B.cpp
#include "StdAfx.h"

#include "B.h"
#include "A.h" //must include A.h
#include <iostream>

B::B(void)
{
}

B::~B(void)
{
}

int B::func()
{
cout<<"This is in B"<<endl;
A a;
return a.m_nItem;
}

3.类成员函数作为友元函数

//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.h
#pragma once
class A;
class B
{
public:
B(void);
~B(void);
int func(A xx);
};
//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");
} 

4. 友元不具有相互性，只具有单项性

5. 友元不能被继承

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

6. 友元不具有传递性

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

7. 友元函数的使用技巧

class CMySingleton
{
public:
friend CMySingleton& InstanceMEC();

private:
CMySingleton() {};
CMySingleton(const CMySingleton &lxSington) {};
~CMySingleton(){};
};

CMySingleton& InstanceMEC()
{
//因为函数InstanceMEC()是类ClxSingletonMEC的友元函数，所以可以访问类所有的成员函数.所以不会有编译错误
static CMySingleton Instance;
return Instance;
}  

//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.h
#pragma once
class A;
class B
{
public:
  B(void);
  ~B(void);
  int func(A xx);
};
//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");
}
posted @ 2021-12-15 16:44  sgggr  阅读(62)  评论(0编辑  收藏  举报