友元函数是指某些虽然不是类成员却能够访问类的所有成员的函数。。类授予它的友元特别的访问权。通常同一个开发者会出于技术和非技术的原因,控制类的友元和成员函数(否则当你想更新你的类时,还要征得其它部分的拥有者的同意)。

// Friend.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "math.h"

class Point
{
private:
 double m_X;
 double m_Y;
public:
 friend double Distance(Point pt0, Point pt1)
 {
  return sqrt((pt0.m_X - pt1.m_X) * (pt0.m_X - pt1.m_X) + (pt1.m_Y - pt0.m_Y) * (pt1.m_Y - pt0.m_Y));
 }
 Point(double mx, double my)
 {
  m_X = mx;
  m_Y = my;
 }
 ~Point()
 {

 }
};

int main(int argc, char* argv[])
{
 Point pnt0(3,0);
 Point pnt1(0,4);
 printf("%f", Distance(pnt0, pnt1));

 //printf("Hello World!\n");
 return 0;
}

 一个类A声明为一个类B的友元类之后,类A就可以任意访问类B的所有 成员(公有的,保护的和私有的).但是,如果一个类D继承自类B, 类B中的友元关系并不会被继承,也就是说,类A是类B的友元但却不是 类B的派生类D的友元.即类A不可以访问类D的保护的和私有的成员. 在上面的代码中,被注释了的部分不能够通过编译,因为D不是A的友 元类,B的友元关系并没有被继承.而在A的Print函数成员中,参数为 基类B的const引用;而实参却可以是D类的对象,从而实现了在A类中 调用D类成员的目的.当然,你完全可以把A声明为D的友元类.对这种 机制的解释:首先,在A的Print函数中,通过B类对象调用其私有的虚 函数(b.Print();),由于A是B的友元,该调用是完全合法的.而在用 D对象调用A的Print函数时时,b.Print()调用动态绑定到了对D类对象 的函数版本的调用.这里,也说明了另外一个问题:类成员的访问控制 只是在编译时有效。

#include "stdafx.h"
#include <iostream>
using namespace std;
#include "math.h"

class B
{
 friend class A;
private:
 virtual void Print()
 {
  std::cout<<"B"<<endl;
 }
};
class D : public B
{
private:
 virtual void Print()
 {
  std::cout<<"D"<<endl;
 }
};
class A
{
public:
 A()
 {
  B b;
  cout<<"A's Constructor";
  b.Print();
 }
 void Print(B & b)
 {
  cout<<"A-->";
  b.Print();
 }
};
int main(int argc, char* argv[])
{
 A a;
 B b;
 D d;
 a.Print(b);
 a.Print(d);
 return 0;
}