闽公网安备 35020302035485号
class MethodTable
{
/************************************
* FRIEND FUNCTIONS
************************************/
// DO NOT ADD FRIENDS UNLESS ABSOLUTELY NECESSARY
// USE ACCESSORS TO READ/WRITE private field members
// Special access for setting up String object method table correctly
friend class ClassLoader;
friend class JIT_TrialAlloc;
friend class Module;
friend class EEClass;
friend class MethodTableBuilder;
friend class CheckAsmOffsets;
...
}
这对于 C# 来说是个新鲜玩意,这一篇我们就来探索下 friend 的底层玩法。在 C++ 中存在两种友元,一个叫 友元函数,一个叫 友元类,我们逐一了解下。
#include<iostream>
using namespace std;
class Person {
public:
Person(int money) :money(money) {}
private:
string name;
int money;
};
int getMoney(const Person& person)
{
int money = person.money;
return money;
}
int main() {
Person p(100);
int age = getMoney(p);
cout << "money: " << age << endl;
}
假定上面的 getMoney 函数想直接提取 Person 的私有字段 money ,这么粗暴的做法,我想是个人都会拒绝,何况是函数了,在现实社会实践中,总有办法能偷出来的 😄,代码中也是一样,比如用 指针 直接暴力偷,如下图所示:
class Person {
//友元列表
friend <返回类型> <函数名> (<参数列表>);
private:
xxxx
public:
xxx
};
看起来非常简单,就是在 类 的开始处定义一个 友元列表 即可,接下来我们修改代码如下:#include<iostream>
using namespace std;
class Person {
friend int getMoney(const Person& person);
public:
Person(int money) :money(money) {}
private:
string name;
int money;
};
//友元函数
int getMoney(const Person& person)
{
int money = person.money;
return money;
}
int main() {
Person p(100);
int age = getMoney(p);
cout << "money: " << age << endl;
}

本质上来说,能不能提取得到,就是 编译器 的一个限定而已,在汇编上没有任何不一样的地方,都是从栈单元中获取数值。
class Person {
//友元列表
friend class 类名;
private:
xxxx
public:
xxx
};
有了这个模板,接下来就可以上代码了。#include <iostream>
using namespace std;
class Person {
friend class Test;
public:
Person(int money) :money(money) {}
private:
string name = "hello";
int money;
};
class Test {
public:
int getMoney(const Person& person) {
int sum = person.money;
return sum;
}
};
int main() {
Person p(100);
Test t;
int money = t.getMoney(p);
cout << "money: " << money << endl;
}
