友元:类可以允许其他类或者函数访问它的非公有成员,方法是令其他类或者函数成为它的友元,声明为哪个类的友元,就可以通过哪个类的对象访问其私有成员
友元的本质:是让其它不属于本类的成员(全局函数,其它类的成员函数)成为类的成员而具备了本类成员的属性,但仍然需要利用该类的对象去访问该类的数据成员(利用t去访问x y z)
友元函数:函数(可以是全局函数,也可是类成员函数)可以作友元,称为友元函数,友元的位置在类中哪个位置都可以 可以在private也可以在public,友元函数能定义在类的内部,这样的函数是隐式内联的。
#include "stdafx.h"
#include <iostream>
using namespace std;
#if 0
同类对象间无私处
异类对象间有友员
#endif
class A; //前向声明
class B
{
public:
//前向声明可以定义引用,所以可以将A进行前向声明
void dis(A &t);
//但前向声明只能确定在此开辟的空间大小 却看不见数据成员x y z
//所以需要只在此处声明,而实现则放到 类A中的 x y z都声明完之后
};
class A
{
public:
//friend void dis(A&t); 等价于 friend void ::dis(A&t);全局函数 命名空间为空
friend void B::dis(A &t);
//此处用到B了 但它不是*或者&类型,所以将B进行前向声明不起作用
private:
int x;
int y;
int z;
};
void B::dis(A &t)
{
cout << t.x << t.y << t.z << endl;
}
//全局函数
//void dis(A &t)
//{
// cout << t.x << t.y << t.z << endl;
//}
int _tmain(int argc, _TCHAR* argv[])
{
A a;
B b;
for (int i = 0; i < 1000; i++)
b.dis(a); //对象a可以通过B类的函数访问A类的数据
}
友元声明:友元声明只能出现在类定义的内部,但是在类内出现的具体位置不限,友元不是类的成员,也不受它所在区域访问控制级别的约束。友元的声明仅仅指定了访问的权限,而非一个通常意义上的函数声明。如果我们希望类的用户能够调用某个友元函数,那么我们就必须在友元声明之外再专门对函数进行一次声明(主要对于友元函数声明和定义都在类内部的情况),一般来说,最好在类定义开始或结束前的位置集中声明友元。
当友元函数在类外进行定义时,对于类而言可以直接调用这个友元函数
class A
{
public:
A(int x, int y, int z)
:m_x(x), m_y(y), m_z(z){}
friend void foo(A& a);
void fun();
void func();
private:
int m_x;
int m_y;
int m_z;
};
void foo(A& a)
{
cout << "A::foo" << endl;
cout << a.m_x << "-" << a.m_y << "-" << a.m_z << endl;
}
void A::fun()
{
foo(*this);
cout << "A::fun" << endl;
}
void A::func()
{
foo(*this);
cout << "A::func" << endl;
}
int main()
{
A a(1, 2, 3);
a.func();
cout << "--------------------------------" << endl;
foo(a);
}
当友元函数在类内进行定义时,如果没有再类的外部提供相应的声明使这个友元函数可见,即使使用声明友元的类的成员,也不能够直接调用这个友元函数
class A
{
public:
A(int x, int y, int z)
:m_x(x), m_y(y), m_z(z){}
friend void foo()
{
cout << "A::foo" << endl;
}
void fun();
void func();
private:
int m_x;
int m_y;
int m_z;
};
void A::fun()
{
//foo(); foo没有在外部声明这里是访问不到的
cout << "A::fun" << endl;
}
void foo(); //类外进行声明
void A::func()
{
foo();
cout << "A::func" << endl;
}
int main()
{
A a(1, 2, 3);
a.func();
cout << "--------------------------------" << endl;
foo();
}
虽然按照C++primer书中所讲友元的访问权限,需要在类外进行声明,但是这样来定义却是不用在类外声明也可以调用,不太理解其中的原因
class A
{
public:
A(int x, int y, int z)
:m_x(x), m_y(y), m_z(z) {}
friend void foo(A& a)
{
cout << "A::foo" << endl;
cout << a.m_x << "-" << a.m_y << "-" << a.m_z << endl;
}
void fun();
void func();
private:
int m_x;
int m_y;
int m_z;
};
void A::fun()
{
foo(*this);
cout << "A::fun" << endl;
}
void A::func()
{
foo(*this);
cout << "A::func" << endl;
}
int main()
{
A a(1, 2, 3);
a.func();
cout << "--------------------------------" << endl;
foo(a);
}