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