外部函數(shù)如何訪問其它類的私有成員,你可能想到的是友元,然而友元會侵入原class的代碼。
今天看到一個黑魔法:
class Bank {
private:
double money = 999;
public:
void check() {
std::cout << "check:" << money << "\n";
}
};
template<auto M>
struct Tunnel;
template<class T, class U, T U::*M>
struct Tunnel<M> {
friend T& sneak(U& u) {
return u.*M;
}
};
template struct Tunnel<&Bank::money>;
double& sneak(Bank&);
int main() {
Bank bank;
bank.check();
auto& take_control = sneak(bank);
auto booty = take_control;
take_control = 0.114514;
std::cout << "booty: " << booty << "\n";
bank.check();
}
這個黑魔法的原理是C++可以顯式實例化模板類,而顯式實例化包括私有成員指針的特化。但這樣還不夠,即使顯式實例化了,取不到私有成員的指針還是會調(diào)用不到這個特化。然而,C++有一個東西叫友元(friend),它除了可以讓友元函數(shù)訪問私有成員,還可以為該函數(shù)提供定義。這樣一來,在友元函數(shù)的定義中使用模板參數(shù)(私有成員指針)訪問私有成員,在外面不需要取得私有成員指針也能調(diào)用該友元函數(shù)。
來源:https://www.zhihu.com/question/521898260/answer/2394522797
還有個此黑魔法的開源庫,用于訪問類的私有成員很方便,看下使用代碼:
class A {
int m_i = 3;
};
ACCESS_PRIVATE_FIELD(A, int, m_i)
void foo() {
A a;
auto &i = access_private::m_i(a);
assert(i == 3);
}
這個開源庫的地址在:https://github.com/martong/access_private
有興趣的朋友可以研究研究。

這里有 一個優(yōu)質(zhì)的C++學(xué)習(xí)圈 等你加入。