我一直在努力思考从C ++中的一些测试代码访问受保护成员函数的最佳方法,这是我的问题:
//in Foo.h
Class Foo
{
protected:
void DoSomething(Data data);
}
//in Blah.h
Class Blah
{
public:
Foo foo;
Data data;
};
//in test code...
Blah blah;
blah.foo.DoSomething(blah.data); // Here's my problem!
目前为止的一些可行解决方案:
欢迎所有建议/见解/意见!
谢谢
答案 0 :(得分:16)
标准完全允许一种方式。
//in Foo.h
class Foo
{
protected:
void DoSomething(Data data);
};
//in Blah.h
class Blah
{
public:
Foo foo;
Data data;
};
//in test code...
struct FooExposer : Foo {
using Foo::DoSomething;
};
Blah blah;
(blah.foo.*&FooExposer::DoSomething)(blah.data);
阅读Hidden features of C++条目以获得解释。
为方便起见,您可以编写一个宏(括号内,以便您也可以将此宏用于带逗号的类型,如vector<pair<A, B>>
):
#define ACCESS(A, M, N) struct N : get_a1<void A>::type { using get_a1<void A>::type::M; }
template<typename T> struct get_a1;
template<typename R, typename A1> struct get_a1<R(A1)> { typedef A1 type; };
现在问题变成了
ACCESS((Foo), DoSomething, GetDoSomething);
Blah blah;
(blah.foo.*&GetDoSomething::DoSomething)(blah.data);
答案 1 :(得分:8)
好的,既然你说它只是一个测试代码,我会建议一些严重的hacky,但会起作用:
struct tc : protected Foo
{
tc(Foo *foo, Data& data)
{
((tc*)foo)->DoSomething(data);
}
};
Blah blah;
tc t(&blah.foo, blah.data);
答案 2 :(得分:7)
一方面,不要那样做。
另一方面,这是一场赌博:
#define protected public
#include "foo.h"
#undef protected
8 - )
但严重的是,为什么DoSomething()
受到保护?可能是因为从外部代码调用它可能会破坏某些东西。在这种情况下,您不应该从测试中调用它。
答案 3 :(得分:3)
我已经完成了
class Foo
{
protected:
void DoSomething(Data data);
public:
#ifdef TEST
void testDoSomething(Data data);
#endif
}
然后使用g ++ -D TEST编译单元测试。
答案 4 :(得分:3)
而不是将private
定义为public
,考虑 ifdefing friendship ,或者更好地考虑该函数是否真的需要属于该类也许只需在cpp中的命名/未命名命名空间中包含某些内容,然后在测试项目中声明即可。
无论如何,请检查this链接,也许您的测试框架会提供类似的功能。
编辑:你考虑从真正的班级继承你的考试班吗?
答案 5 :(得分:2)
您可以将继承与转发功能结合使用:
class Foo
{
protected:
void DoSomething(Data data);
}
class test_Foo : public Foo
{
public:
void testDoSomething(Data data)
{
DoSomething(data);
}
}
答案 6 :(得分:2)
使用包装器如下:
// Foo.h unchanged
// Blah.h unchanged
// test code
class FooTest : public Foo { friend void test(); }; // make friends
void test()
{
Blah blah;
static_cast<FooTest*>(&blah.foo)->DoSomething(blah.data); // Here's no problem!
}
答案 7 :(得分:1)
如果它是严格的测试代码,你可以做...
#define protected public
#include "Foo.h"
// test code
#undef protected