此处参考 博客园 zhuguanhao 的文章,在此感谢 https://www.cnblogs.com/zhuguanhao/p/6286145.html
友元函数(类)的概念
1.是一种允许非类成员函数访问类的私有成员的一种机制。可以把一个函数指定为类的友元,也可以把整个类指定为另一个类的友元。
2. (1) 函数前面加一个 friend 修饰,友元函数需要在类体里面申明,但是友元函数并不是这个类的成员函数。友元的声明以friend开始,它只能出现在类定义的内部,友元声明可以出现在类中的任何地方且不受类中访问控制(private、public、protected)的影响。通常,将友元声明成组地放在类定义的开始或结尾是个好主意。
(2) 如果友元函数是另一个类A的成员函数,那么这个友元函数的作用域和A相同。如果友元函数并不是某个类的成员函数,那么它的作用域和一般函数相同。
3.友元函数破坏了面向对象程序设计类的封装。
牛客网上做题积累
1. 友元函数有对象做参数时,可以在类内部定义函数体,没有对象做参数时,必须在类外定义函数体。
#include <math.h>
#include <iostream>
using namespace std;
class Point
{
friend void Distance( const Point & p1, const Point & p2 )
{
cout<<"执行 Distance"<<endl;
}
friend void Distance2( const Point & p1, const Point & p2 );
friend void Distance3();
friend void Distance4()
{
cout<<"执行 Distance4"<<endl;
}
private:
int x_;
int y_;
};
void Distance2( const Point & p1, const Point & p2 )
{
cout<<"执行 Distance2"<<endl;
}
void Distance3()
{
cout<<"执行 Distance3"<<endl;
}
int main( void )
{
Point p1,p2;
Distance (p1,p2); //友元函数中有对象做参数 在类内定义
Distance2(p1,p2); //友元函数中有对象做参数 在类外定义
Distance3(); //友元函数中没有对象参数 在类外定义
//Distance4(); //友元函数中没有对象参数 在类内定义 调用错误
return(0);
}
友元函数的使用(主要是用在类中的操作符重载)
#include <iostream>
using namespace std;
class Test
{
public:
Test(int m,int n): a(m),b(n)
{
cout<<"进入到构造函数"<<endl;
}
void get()
{
cout<<"a的值="<<a<<endl;
cout<<"b的值="<<b<<endl;
}
private:
//前面用friend修饰,函数放在类中哪里都可以,
//放在 public 下也行 private 下也行
friend void modify(Test* obj);
int a;
int b;
};
//
//这是用 引用 的方法
//void modify(Test & obj) { obj.a = 100; }
//这是用指针的方法
void modify(Test * obj) { obj->a = 100; }
int main()
{
Test t1(1,2);
t1.get();
modify(&t1); 这是指针的方法
// modify(t1); 这是引用的方法
t1.get();
return 0;
}
友元类(用的很少)
友元类的所有成员函数都是另一个类的友元函数,都可以访问另一个类中的隐藏信息(包括私有成员和保护成员)。当希望一个类可以存取另一个类的私有成员时,可以将该类声明为另一类的友元类。友元类通常被设计为一种对数据操作或类之间传递消息的辅助类。
1.一个类A作为另一个类B的友元类,可以访问B的所有成员。
2. 格式 :friend class 类名;
3.友元类的注意事项:
(1) 友元关系是单向的,B是A的友元类,但A并不一定是B的友元类
(2) 友元关系不能被传递,也不能被继承
A是B的友元类,B是C的友元类,但A不一定是C的友元类,
A是B的友元类,C继承自A,但C不一定是B的友元类。
(3) 友元关系不能被继承
友元类的使用
//一个简单的友元类例程
#include <iostream>
using namespace std;
class TestA
{
public:
friend class TestB; //此处声明 TestB 是 TestA的友元类
private:
int a;
};
class TestB
{
public:
void SetData(int tmp)
{
testa.a = tmp; //调用TestA中的a
}
void GetData()
{
cout<<"a的值 = "<<testa.a<<endl;
}
private:
TestA testa;
};
int main()
{
TestB testb; //这里直接用TestB类的对象去设置 TestA类中参数,却没有声明TestA对象
testb.SetData(100);
testb.GetData();
return 0;
}