Zyuzhi Blog - 私有成员函数
type: channel
link: https://blog.zyuzhi.me/tag/%E7%A7%81%E6%9C%89%E6%88%90%E5%91%98%E5%87%BD%E6%95%B0/
items: 访问C++的private成员变量、成员函数的方法

访问C++的private成员变量、成员函数的方法
type: item
date: 2018-10-25T18:36:00+08:00
description: 源起最近写代码的时候，碰到了一个PCL的bug，本想通过继承的方式把这个bug fix掉，但是无奈我必须访问基类的私有成员函数和私有成员变量。正常情况下，我是不可能从外部访问到一个类的私有成员变量和私有成员函数的，但是总有Tricky的方法。经过Google，找到了下面这么几个方法。首先看我们的这个代码。class A{ private: int v; void f(); public: A() {} }; void A::f() { std::cout << "private f function" << std::endl; }假设我们有A这个类，这个类有一个私有成员变量v和一个私有成员函数f，现在我们要读写v或是调用函数f。宏定义Hack-private变public我们可以用宏定义的Hack方法改变函数A内部函数、变量的访问权限。#define private public #define protected public class A{ private: int v; void f(); public: A() {} }; #undef private #undef protected void A::f() { std::cout << "private f function" << std::endl; } int main() { A a; a.v = 10; a.f(); return 0; }缺点这种Hack方式比较暴力，完全改变了类的访问限定。这种对类的默认访问限定不起作用，比如：class A { int v; void f(); public: A() {} };类A的变量v和函数f没有显式的访问限定，默认都是私有的。这种是没办法处理的。对于只有头文件和lib库的访问限定Hack也是有用的，只需要在包含的头文件前后加上#define和#undef就行了。#define private public #include "a.h" #undef private // 再包含其他的头文件。。也可以将private限定变更为protected，然后以继承的方式同样也可以访问到原先私有的成员函数和成员变量宏定义Hack-友元函数、友元类在上面直接改变类的访问限定的方法上，可以发展出来另一种更好一些的方法——友元类。这种方法不改变外部代码对于类的访问权限，只有某个类才能访问到所有成员变量和成员函数。class Hack; #define private friend class Hack; private #define public friend class Hack; public #define protected friend class Hack; protected class A { private: int v; void f(); public: A() {} }; #undef private #undef public #undef protected void A::f() { std::cout << "private f function" << std::endl; } class Hack { public: static void set_v(A& a, int val) { a.v = val; } static void func_f(A& a) { a.f(); } }; int main() { A a; Hack::set_v(a, 10); Hack::func_f(a); return 0; }这种方式就相对好一些了，其他代码也没有办法访问A的私有成员函数和成员变量，所有的操作必须通过Hack这个类完成。而且对于没有显式private的也是有用的。同样，对于只有头文件和lib库的访问限定Hack也是有用的，只需要在包含的头文件前后加上#define和#undef就行了。#define private friend class Hack; private #define public friend class Hack; public #define protected friend class Hack; protected #include "a.h" #undef private #undef public #undef protected // 再包含其他的头文件。。类的强制转换Hack先说方法，请看代码。#include <iostream> class A{ private: int v; void f(); public: A() {} void print(); }; void A::f() { std::cout << "private f fun…