الوصول إلى وظائف الأعضاء المحمية من رمز الاختبار في C ++
سؤال
لقد كنت أرفف ذهني في محاولة للتفكير في أفضل طريقة للوصول إلى وظيفة عضو محمي من بعض رمز الاختبار في 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!
بعض الحلول الممكنة حتى الآن:
جميع المشورة / البصيرة / الآراء هي موضع ترحيب!
شكرا
المحلول
حسنا، نظرا لأنك تقول أنه ليس سوى رمز الاختبار الذي سأقترح شيئا بجدية بجدية ولكنه سيعمل:
struct tc : protected Foo
{
tc(Foo *foo, Data& data)
{
((tc*)foo)->DoSomething(data);
}
};
Blah blah;
tc t(&blah.foo, blah.data);
نصائح أخرى
هناك طريقة مسموح بها تماما بالمعيار.
//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);
إقرأ ال ميزات مخفية من 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);
على يدا واحدة، لا تفعل ذلك.
من ناحية أخرى، إليك مقامرة:
#define protected public
#include "foo.h"
#undef protected
8-)
ولكن على محمل الجد، لماذا DoSomething()
محمي؟ ربما لأن الاتصال به من الرمز الخارجي يمكن كسر شيء ما. في هذه الحالة، يجب ألا تدعوها من اختباراتك.
لقد فعلت
class Foo
{
protected:
void DoSomething(Data data);
public:
#ifdef TEST
void testDoSomething(Data data);
#endif
}
ثم ترجمة اختبارات الوحدة الخاصة بك مع اختبار G ++ -D.
بدلا من IFFEFING. private
ل public
, ، انصح الصداقة IFFIFING, ، أو أفضل مرة أخرى إذا كانت هذه الوظيفة حقا يحتاج إلى الانتماء إلى تلك الفئة، ربما يكفي أن يكون لديك شيء في مساحة الاسم المسماة / لم تكشف عن اسمها في CPP، ثم أعلن في مشروع اختبار.
على أي حال، تحقق هذه الرابط، ربما يوفر إطار عمل الاختبار الخاص بك وظيفة مماثلة.
تعديل: هل فكرت في ورث فئة الاختبار من صفك الحقيقي؟
يمكنك استخدام الميراث مع وظائف الشحن:
class Foo
{
protected:
void DoSomething(Data data);
}
class test_Foo : public Foo
{
public:
void testDoSomething(Data data)
{
DoSomething(data);
}
}
استخدام المجمع على النحو التالي:
// 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!
}
إذا كان رمز الاختبار بدقة، فيمكنك القيام به ...
#define protected public
#include "Foo.h"
// test code
#undef protected