获得在C++中测试的私人成员的访问权限

Gaining access to private members for testing in C++

本文关键字:成员 访问 访问权 权限 C++ 测试      更新时间:2023-10-16

我正在开发解决大约100个方程的代码。这些方程中的大多数都是在私人成员中计算的,因为最终用户并不关心它们。但是,现在我知道了。所以,当我开发代码时,我想有一种快速的方法来测试私人成员。

下面的代码给出了我想要的基本行为,但它不起作用(隐私问题)。如果这种行为是可能的,我将感谢任何帮助。

// Includes
#include <stdio.h>
// I want a general test class that can access private members
template <class Name> class TestClass{
    public:
        TestClass(Name& input) : the_class(input){}
        Name& operator()(){ return the_class; }
        Name& the_class;
};
// The class I want to test
class ClassA{
    public:
        friend class TestClass<ClassA>; // I hoped this would do it, but it doesn't
        ClassA(){}              
    private:
        void priv(){ printf("a private functionn"); }
};

// Main function that preforms the testing
int main (){
    ClassA a;
    TestClass<ClassA> b(a);
    b().priv(); // I want to do this
}

您已经将友谊授予TestClass<ClassA>,但您却在main()中维护友谊。

您的选择是:

  • TestClass<>中编写一个调用the_class.priv()的转发函数
  • 将友谊授予实际需要它的函数。(我想在您的实际程序中,这并不是真正的main()。)

对此有不同的方法。从高级角度来看,您可以在TestClass适配器中提供与测试类型中相同的功能,并让它转发请求。另一种选择是与一个测试类交朋友,该测试类将实际执行成员函数中的测试。


下面的代码没有编译,它显示了要采取的方法,但细节已经关闭。阅读Kerrek在评论中链接的文章以了解更多细节


最后,如果你想滥用你的C++-fu,你可以通过使用显式模板实例化和成员指针来破坏访问说明符(我是在脑海中写这篇文章的,它可能不会编译,但想法是存在的……如果出现编译器错误,就与之斗争):

template <typename T, void (T::*Ptr)() >
struct accessor {
   typedef void (T::*ptr_t)();
   static ptr_t ptr;
};
template <typename T, void (T::*Ptr)() >
accessor<T,Ptr>::ptr_t accessor<T,Ptr>::ptr = Ptr;
template accessor<ClassA, &ClassA::priv>;
typedef accessor<ClassA, &ClassA> priv_accessor;
int main() {
   ClassA a;
   (a.*priv_accessor::ptr)();
}

这里的方法使用模板实例化来中断访问,因为模板显式实例化的参数不检查访问(否则不可能用私有成员实例化该模板,因为显式模板实例化必须在命名空间级别进行,并且不能与命名空间交朋友)