我想實作一個簡單的測驗結構。下面是我創建基類和派生類的方法。
testBase.h:
class TestBase {
public:
TestBase() {}.
virtual void TestStart()= 0;
virtual void TestEnd()= 0;
void RunTest() {
//I need code here to trigger a chain of calls.
}
};
classifierTest.h:
#include "testBase.h"/span>
class ClassifierTest。public TestBase
{
public:
ClassifierTest() {
}
void TestStart()。
void TestEnd;
void Test1()。
void Test2;
void Test3()。
};
classifierTest.cpp:
#include " classifierTest.h"
void ClassifierTest::TestStart() {
}
void ClassifierTest::TestEnd() {
}
void ClassifierTest::Test1(){
}
void ClassifierTest::Test2(){ }
}
void ClassifierTest::Test3(){ }
main函式:
ClassifierTest *classifierTest = new ClassifierTest() 。
classifierTest->RunTest()。
假設Test1()、Test2()和Test3()是我的測驗方法,我將來可能在這里添加更多的測驗。
我的目標是,當我在主函式中呼叫RunTest()時,這些測驗方法被逐一呼叫,在TestStart()之后和TestEnd()之前。
所以他們會像這樣運行:
TestStart()Test1()TestEnd()/code>TestStart()Test2()TestEnd()TestStart()Test3()TestEnd()我不想在基類中特別添加測驗方法。但問題是如何從RunTest()觸發這些連鎖呼叫。這樣基類就會觸發它不知道的方法。
我相信應該是這樣的:在基類中添加測驗方法。
我相信這應該是像.net中的反射一樣的東西。
uj5u.com熱心網友回復:
你基本上是在要求反射,這在C 中是不存在的(還沒有)。現在的問題是你愿意做出什么樣的妥協。
如果你愿意寫一些代碼來手動注冊測驗函式,那么它們就不需要是成員,一個可能的解決方案是:
如果你愿意寫一些代碼來手動注冊測驗函式,那么它們就不需要是成員。
#include <functional>/span>
#include <vector>
#include <iostream>
class TestBase {
public:
TestBase() {}.
virtual void TestStart()= 0;
virtual void TestEnd()= 0;
void RunTest() {
for (const auto& test_fun : test_functions){
TestStart()。
test_fun()。
TestEnd()。
}
}
using test_function = std::function<void()> 。
void register_test(const test_function& fun){ test_functions. push_back(fun); }
private:
std::vector<test_function> test_functions。
};
class ClassifierTest。public TestBase
{
public:
ClassifierTest() {
register_test([](){ std::cout << "test 1
";})。
register_test([] (){ std::cout << "test 2
";})。
}
void TestStart() { std::cout << "test start
";}
void TestEnd() { std::cout << " test end
";}
};
int main() {
ClassifierTest{}.RunTest()。
test start
測驗 1
測驗結束
測驗開始
測驗 2
測驗結束
注意,如果你捕獲了this,lambdas可以使用成員,所以和你最初的方法沒有太大區別,撰寫的代碼量也是相當的:
class ClassifierTest2。public TestBase
{
public:
ClassifierTest2() {
register_test([this](){ std::cout << "test 1, x ="<< x << "
";})。
register_test([this](){ std::cout << "test 2, x = " < < x << "
";})。
}
void TestStart() { x; std::cout < < "test start
"; }
void TestEnd() { std::cout << " test end
";}
private:
int x = 0;
};
int main() {
ClassifierTest2{}.RunTest()。
test start
測驗 1, x = 1
測驗結束
測驗開始
測驗 2, x = 2
測驗結束
正如在評論中已經提到的,如果你手動注冊
標籤:TestStart和TestEnd,那么就不需要派生類了。它可以只是一個帶有register_test_start(std::function<void()>)和register_test_end(std::function<void()>)的類,或者將它們作為引數傳遞給構造器。
