C++中的friend函数详细解析

2020-01-06 15:58:55王振洲

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. 友元不具有相互性,只具有单项性

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

5. 友元不能被继承

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

6. 友元不具有传递性

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

7. 友元函数的使用技巧

在用C++实现单例模式时,可以利用友元函数实例化对象。然后把类的构造函数和析构函数都设计成私有函数。


class CMySingleton 
{ 
public: 
  friend CMySingleton& InstanceMEC(); 
 
private: 
  CMySingleton() {}; 
  CMySingleton(const CMySingleton &lxSington) {}; 
  ~CMySingleton(){}; 
}; 
 
CMySingleton& InstanceMEC() 
{ 
  //因为函数InstanceMEC()是类ClxSingletonMEC的友元函数,所以可以访问类所有的成员函数.所以不会有编译错误 
  static CMySingleton Instance;  
  return Instance; 
}