C++ 友元函数(Friend)
在类的外部,任何实例访问类的 private 或 protected 成员都是被禁止的,这是出于安全性的考虑。但是很多时候,出于实用性的考虑,的确需要从外部访问类的 private 或 protected 的成员,这可以在 C++ 中通过关键字 friend 来实现。
友元(friend)机制允许一个类将对其非公有成员(private 和 protected 成员)的访问授予指定的函数或类。友元函数必须要在类的内部进行声明,友元不是授予友元关系的那个类成员,出于编码风格的考虑,通常将友元声明橙组地放置在类定义的开头或结尾处
一、全局函数作为友元
[cpp]
// Friend_Global.cpp
#include <iostream>
using namespace std;
class Base {
int value; // 私有成员
protected:
string str; // 保护成员
public:
Base(const string newStr, const int ii) :
str(newStr), value(ii) {}
friend void view(Base&); // 声明friend的全局函数
};
void view(Base& b) { // 接受的是基类对象
cout << "string = " << b.str << endl
<< "value = " << b.value << endl;
return ;
}
int main() {
Base b("Base", 49);
view(b);
/*
// 任何实例,在类的外部试图访问
// 类的private或protected成员都是被禁止的
cout << "string = " << b.str << endl
<< "value = " << b.value << endl;
*/
return 0;
}
运行结果:
值得注意的是,使用friend关键字修饰的全局函数void view(Base& b)并非是Base类的成员函数,它仅仅是全局函数
二、其它类的成员函数成为友元
[cpp]
// Friend_Class.cpp
#include <iostream>
using namespace std;
class Y; // 因为在类X中的view函数中出现了Y,因此必须事先声明类Y
class X {
public:
/*
参数类型声明为指针,因为类Y的定义在下方,
在Y的定义之前,编译器或许并不知道应该为Y的对象
分配多大的内存空间,而如果是Y*指针的话,编译器
作了一次不完全的类型匹配,编译器知道如何传递一个
地址,这一地址有具体的大小,而不管被传递的是什么
对象,即使它还没有完全知道这种对象类型的大小
虽然事实上传递对象也是可以的,但是在这种情况下,
传递一个对象的地址更为安全!
*/
void view(const Y*);
};
class Y {
int value; // 私有成员
protected:
string str; // 保护成员
public:
Y(const string newStr, const int ii) :
str(newStr), value(ii) {}
friend void X::view(const Y*); // 声明friend的全局函数
};
void X::view(const Y* y) {
cout << "string = " << y->str << endl
<< "value = " << y->value << endl;
return ;
}
int main() {
Y y("Base", 49);
X x;
x.view(&y);
return 0;
}
运行结果:
补充:软件开发 , C++ ,