通过基础class中的方法触发派生class的添加方法
Trigger added methods of derived class by method in base class
我想实现一个简单的测试结构。下面是我如何创建基础 class 和派生 class.
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"
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(){
}
主要功能:
ClassifierTest *classifierTest = new ClassifierTest();
classifierTest->RunTest();
假设Test1()
、Test2()
和Test3()
是我的测试方法,以后我可能会在这里添加更多测试。
我的目标是当我在main函数中调用RunTest()
的时候,然后这些测试方法一个一个调用,在TestStart()
之后,TestEnd()
.
之前
所以他们会 运行 喜欢:
TestStart()
Test1()
TestEnd()
TestStart()
Test2()
TestEnd()
TestStart()
Test3()
TestEnd()
我不想在基础中专门添加测试方法class。但问题是如何从 RunTest() 触发这些调用链。所以它不知道它们的基本触发方法。
我认为它应该像 .net 中的反射一样?
您基本上是在要求 C++ 中不存在的反射(目前)。现在的问题是你愿意做出什么样的妥协
如果您愿意编写一些代码来手动注册测试函数,那么他们就不需要成为成员,一个可能的解决方案是:
#include <functional>
#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\n";});
register_test([](){ std::cout << "test 2\n";});
}
void TestStart() { std::cout << "test start\n";}
void TestEnd() { std::cout << "test end\n";}
};
int main() {
ClassifierTest{}.RunTest();
}
test start
test 1
test end
test start
test 2
test end
请注意,如果您捕获 this
lambda 可以使用成员,因此与您的初始方法没有太大区别,并且要编写的代码量也相当:
class ClassifierTest2: public TestBase
{
public:
ClassifierTest2() {
register_test([this](){ std::cout << "test 1, x = " << x << "\n";});
register_test([this](){ std::cout << "test 2, x = " << x << "\n";});
}
void TestStart() { ++x;std::cout << "test start\n";}
void TestEnd() { std::cout << "test end\n";}
private:
int x = 0;
};
int main() {
ClassifierTest2{}.RunTest();
}
test start
test 1, x = 1
test end
test start
test 2, x = 2
test end
如评论中所述,如果您也手动注册 TestStart
和 TestEnd
,则不需要派生的 classes。它可以只是 class Test
和 register_test_start(std::function<void()>)
和 register_test_end(std::function<void()>)
或将它们作为参数传递给构造函数。
我想实现一个简单的测试结构。下面是我如何创建基础 class 和派生 class.
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"
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(){
}
主要功能:
ClassifierTest *classifierTest = new ClassifierTest();
classifierTest->RunTest();
假设Test1()
、Test2()
和Test3()
是我的测试方法,以后我可能会在这里添加更多测试。
我的目标是当我在main函数中调用RunTest()
的时候,然后这些测试方法一个一个调用,在TestStart()
之后,TestEnd()
.
所以他们会 运行 喜欢:
TestStart()
Test1()
TestEnd()
TestStart()
Test2()
TestEnd()
TestStart()
Test3()
TestEnd()
我不想在基础中专门添加测试方法class。但问题是如何从 RunTest() 触发这些调用链。所以它不知道它们的基本触发方法。
我认为它应该像 .net 中的反射一样?
您基本上是在要求 C++ 中不存在的反射(目前)。现在的问题是你愿意做出什么样的妥协
如果您愿意编写一些代码来手动注册测试函数,那么他们就不需要成为成员,一个可能的解决方案是:
#include <functional>
#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\n";});
register_test([](){ std::cout << "test 2\n";});
}
void TestStart() { std::cout << "test start\n";}
void TestEnd() { std::cout << "test end\n";}
};
int main() {
ClassifierTest{}.RunTest();
}
test start
test 1
test end
test start
test 2
test end
请注意,如果您捕获 this
lambda 可以使用成员,因此与您的初始方法没有太大区别,并且要编写的代码量也相当:
class ClassifierTest2: public TestBase
{
public:
ClassifierTest2() {
register_test([this](){ std::cout << "test 1, x = " << x << "\n";});
register_test([this](){ std::cout << "test 2, x = " << x << "\n";});
}
void TestStart() { ++x;std::cout << "test start\n";}
void TestEnd() { std::cout << "test end\n";}
private:
int x = 0;
};
int main() {
ClassifierTest2{}.RunTest();
}
test start
test 1, x = 1
test end
test start
test 2, x = 2
test end
如评论中所述,如果您也手动注册 TestStart
和 TestEnd
,则不需要派生的 classes。它可以只是 class Test
和 register_test_start(std::function<void()>)
和 register_test_end(std::function<void()>)
或将它们作为参数传递给构造函数。