I want to implement a simple test structure. Here is how I created base class and derived 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(){
}
main function:
ClassifierTest *classifierTest = new ClassifierTest();
classifierTest->RunTest();
Suppose Test1(), Test2() and Test3() are my test methods, and I may add more tests here in future.
My goal is that when I call RunTest() in the main function, then these test methods are called one by one, after TestStart(), and before TestEnd().
so they would run like:
TestStart()
Test1()
TestEnd()
TestStart()
Test2()
TestEnd()
TestStart()
Test3()
TestEnd()
I don't want to specifically add test method in the base class. But the question is how to trigger these chain of calls from RunTest(). So the base trigger methods that it doesn't know about them.
I believe it should be sth like reflection in .net?
You are basically asking for reflection which isnt present in C++ (yet). Now the quesiton is what comprosmise you are willing to make.
If you are fine with writing some code to manually register the test functions, then they don't need to be members and a possible solution is this:
#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();
}
Output:
test start
test 1
test end
test start
test 2
test end
Note that if you capture this the lambdas can use members, so there isnt much difference to your initial approach and the amount of code to write is also comparable:
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();
}
Output:
test start
test 1, x = 1
test end
test start
test 2, x = 2
test end
As mentioned already in a comment, if you manually register TestStart and TestEnd as well, then there is no need for the derived classes. It could be just a class Test with register_test_start(std::function<void()>) and register_test_end(std::function<void()>) or pass them as parameters to the constructor.
Related
I tried to count the number of test classes, like this:
int classCount = 0;
class TestClass2 : public testing::Test {
protected:
static void SetUpTestCase() {
}
static void TearDownTestCase() {
}
virtual void SetUp() { classCount++; }
virtual void TearDown() {}
};
TEST(TestClass1, classCount) {
cout << typeid(*this).name() << endl;
EXPECT_EQ(1, classCount);
}
Unfortunately, the classCount is 0. I was expecting that when TestClass1_xxxx class is initialized, the classCount will +1 by virtual void SetUp() { classCount++; }. But actually it's not called. I added cout inside virtual void SetUp() { classCount++; } but still saw not console output.
So my question is, when is virtual void SetUp() {} begin called? Is it called automatically in some way?
You can remove the whole class and the code will still compile.
int classCount = 0;
TEST(TestClass1, classCount) {
cout << typeid(*this).name() << endl;
EXPECT_EQ(1, classCount);
}
Because class TestClass2 is a test fixture class and should be used with the macro TEST_F.
int classCount = 0;
class TestClass2 : public testing::Test {
protected:
static void SetUpTestCase() {
}
static void TearDownTestCase() {
}
void SetUp() override { classCount++; }
void TearDown() override {}
};
// ▼▼
TEST_F(TestClass1, classCount) {
cout << typeid(*this).name() << endl;
EXPECT_EQ(1, classCount);
}
What is you real problem? That code smells XY problem.
I write c++ with c++11 and have a question as title.
Ex.
class Hi {
public:
Hi(){};
test() {cout << "test" << endl;};
}
void noop(){
; // noop
};
int main(){
Hi hi();
hi.test = noop; // just example, not real case
return 0;
}
Is that possible to replace test() of class Hi to a noop function in runtime!? Thanks.
You can't replace any function at runtime, whether class member or not.
However, you can achieve the desired effect by using a variable.
(This is yet another example of the "add a level of indirection" method of solving problems.)
Example:
class Hi {
public:
Hi(): test([this]() { do_test(); }) {}
std::function<void()> test;
void do_test() { cout << "test" << endl; }
};
void noop(){}
int main(){
Hi hi;
hi.test(); // Outputs 'test'
hi.test = noop;
hi.test(); // Does nothing
}
You have to think object oriented. In this case you have to elevate your function to be an object we can name it MethodClass then your function in the class Hi will be a pointer to that class. Below a simple example
#include <memory>
class BaseMethodClass
{
public:
virtual void method() = 0;
};
class MethodClass1 : public BaseMethodClass
{
public:
virtual void method()
{
// your implementation here
}
};
class MethodClass2 : public BaseMethodClass
{
public:
virtual void method()
{
// your implementation here
}
};
class Hi
{
public:
Hi() { method = nullptr; };
void setMethod(BaseMethodClass* m) { method.reset(m); }
void test() { if (method) method->method(); };
private:
std::shared_ptr<BaseMethodClass> method;
};
int main()
{
Hi hi;
hi.setMethod(new MethodClass1());
hi.test();
hi.setMethod(new MethodClass2());
hi.test();
return 0;
}
This way you can override your methos as you want not just noop
I have a templated class TaskRunner that takes a polymorphic type Task and I want to create a container of shared pointers to them.
class Task {
virtual void run() = 0;
};
class LoudTask : Task {
void run() {
std::cout << "RUNNING!" << std::endl;
}
};
class QuietTask : Task {
void run() {
std::cout << "running!" << std::endl;
}
};
template<typename T> class TaskRunner {
public:
TaskRunner<T>() {
task = std::make_unique<T>();
}
private:
std::unique_ptr<T> task;
};
using Runner = std::shared_ptr<TaskRunner<Task>>;
However I get error: no matching member function for call to 'push_back' with:
std::vector<Runner> runners;
runners.push_back(std::make_shared<TaskRunner<QuietTask>>());
runners.push_back(std::make_shared<TaskRunner<LoudTask>>());
Due to:
note: candidate function not viable: no known conversion from 'shared_ptr<TaskRunner>' to 'const shared_ptr<TaskRunner>' for 1st argument
Implemented IgorTandetnik's suggestion, and it works for me:
#include <iostream>
#include <memory>
#include <vector>
class Task {
virtual void run() = 0;
};
class LoudTask : Task {
public:
void run() {
std::cout << "RUNNING!" << std::endl;
}
};
class QuietTask : Task {
public:
void run() {
std::cout << "running!" << std::endl;
}
};
class TaskRunnerBase
{
public:
virtual void run() =0;
};
template <class T>
class TaskRunner: public TaskRunnerBase {
public:
TaskRunner():
task(std::make_unique<T>()) {
}
void run() override
{
task->run();
}
private:
std::unique_ptr<T> task;
};
int main()
{
using Runner = std::shared_ptr<TaskRunnerBase>;
std::vector<Runner> runners;
runners.push_back(std::make_shared<TaskRunner<QuietTask>>());
runners.push_back(std::make_shared<TaskRunner<LoudTask>>());
runners[0]->run();
runners[1]->run();
}
Output:
running!
RUNNING!
Note however that TaskRunner doesn't need to be a template; as it is currently implemented above, it has a kind of double role: (1) task factory, and (2) container and runner of tasks.
paolo's answer separates this out nicely, there, the factory aspect is moved to the main function.
If TaskRunner is supposed to run tasks that inherit from Task only, you may consider de-templatizing it:
#include <iostream>
#include <memory>
#include <vector>
class Task {
public:
virtual void run() = 0;
};
class LoudTask : public Task {
public:
void run() override { std::cout << "RUNNING!" << std::endl; }
};
class QuietTask : public Task {
public:
void run() override { std::cout << "running!" << std::endl; }
};
class TaskRunner {
public:
explicit TaskRunner(std::unique_ptr<Task>&& task_)
: task(std::move(task_)) {}
void run() {
if (this->task) this->task->run();
}
private:
std::unique_ptr<Task> task;
};
int main() {
using Runner = std::shared_ptr<TaskRunner>;
std::vector<Runner> runners;
runners.push_back(
std::make_shared<TaskRunner>(std::make_unique<QuietTask>()));
runners.push_back(
std::make_shared<TaskRunner>(std::make_unique<LoudTask>()));
for (auto& runner : runners) runner->run();
}
This is another implementation that eliminates the need for another inheritance hierarchy and vtable since we already accomplished that with the Task hierarchy:
#include <iostream>
#include <vector>
class Task {
public:
virtual void run() = 0;
};
class LoudTask : public Task {
public:
void run() {
std::cout << "RUNNING!" << std::endl;
}
};
class QuietTask : public Task {
public:
void run() {
std::cout << "running!" << std::endl;
}
};
class TaskRunner {
public:
TaskRunner(std::unique_ptr<LoudTask> task) : m_task{ std::unique_ptr<Task>(task.release()) } {}
TaskRunner(std::unique_ptr<QuietTask> task) : m_task{ std::unique_ptr<Task>(task.release()) } {}
void run()
{
m_task->run();
}
private:
std::unique_ptr<Task> m_task;
};
using Runner = std::shared_ptr<TaskRunner>;
int main()
{
std::vector<Runner> runners;
runners.push_back(std::make_shared<TaskRunner>(std::make_unique<QuietTask>()));
runners.push_back(std::make_shared<TaskRunner>(std::make_unique<LoudTask>()));
runners[0]->run();
runners[1]->run();
}
I would like to have a child class Handler that handles multiple callbacks and transfers data from one class to another. However, the base classes B1 and B2can have different implementations for its members.
Below a way to implement the behavior I want. I think there should be a better way but cannot figure it out.
// Example program
#include <iostream>
#include <string>
template <class T>
class IBase
{
public:
IBase()
{
object = new T(*this);
};
~IBase()
{
delete object;
}
virtual void ValidateCallback()
{
};
void RxCallback()
{
object->RxCallback();
};
void Send()
{
object->Send();
};
T* object;
};
class C1
{
public:
virtual void RxCompleteCallback() = 0;
void RxParse()
{
std::cout << "Parse C1" << std::endl;
RxCompleteCallback();
};
};
class C2
{
public:
virtual void RxCompleteCallback() = 0;
void RxParse()
{
std::cout << "Parse C2" << std::endl;
RxCompleteCallback();
};
};
class B1 : public C1
{
public:
B1(IBase<B1> &handler )
{
ihandler = &handler;
};
void DoSomething()
{
std::cout << "DoSomething B1" << std::endl;
ihandler->ValidateCallback();
};
void RxCompleteCallback() override
{
std::cout << "DoSomething other than B2" << std::endl;
std::cout << "RxCompleteCallback" << std::endl;
};
void RxCallback()
{
RxParse();
};
void Send()
{
DoSomething();
};
IBase<B1> * ihandler;
};
class B2 : public C2
{
public:
B2(IBase<B2> &handler )
{
ihandler = &handler;
};
void DoSomething()
{
std::cout << "DoSomething B2" << std::endl;
ihandler->ValidateCallback();
};
void RxCompleteCallback() override
{
std::cout << "DoSomething other than B1" << std::endl;
std::cout << "RxCompleteCallback" << std::endl;
};
void RxCallback()
{
RxParse();
};
void Send()
{
DoSomething();
};
IBase<B2> * ihandler;
};
class Validate
{
public:
void CalculateValidation()
{
std::cout << "Calculate validation" << std::endl;
};
};
template <class T>
class Handler : public IBase<T>, public Validate
{
public:
void ValidateCallback() override
{
std::cout << "ValidateCallback" << std::endl;
CalculateValidation();
};
void Receive()
{
IBase<T>::RxCallback();
};
void Send()
{
IBase<T>::Send();
}
};
int main()
{
Handler<B1> handler1;
handler1.Receive();
handler1.Send();
std::cout << std::endl;
Handler<B2> handler2;
handler2.Receive();
handler2.Send();
}
Output:
Parse C1
DoSomething other than B2
RxCompleteCallback
DoSomething B1
ValidateCallback
Calculate validation
Parse C2
DoSomething other than B1
RxCompleteCallback
DoSomething B2
ValidateCallback
Calculate validation
There are several ways to do this in C++. It's hard to say what the best way is, it depends on how you will use it, and the example you gave is too simple to recommend a specific way. Normally, I'd say you want to derive your protocol-specific classes from Handler, instead of the other way around, so you'd write:
class Handler {
public:
virtual void Receive() {};
virtual void Send() {};
};
class B1: public Handler {
virtual void Receive() {
...
}
virtual void Send() {
...
}
};
int main() {
B1 handler1;
handler1.Receive();
...
}
The main issue here is that you need to use virtual member functions here, otherwise the base class doesn't know which derived class's implementation to call. But it does allow you to pass a Handler * as an argument to another function, which will then work with any derived class without needing any templating.
Another option is to use the curiously recurring template pattern, which would look like:
template <typename T>
class Handler {
void Receive() {
static_cast<T*>(this)->Receive();
}
void Send() {
static_cast<T*>(this)->Send();
}
};
class B1: public Handler<B1>
{
void Receive() {
...
}
void Send() {
...
}
};
int main() {
B1 handler1;
handler1.Receive();
...
}
This avoids virtual methods.
It is also quite similar to your class Handler, but it has the advantage that it doesn't need the T *object member variable.
I'm using multiple inheritance in C++ and extending base methods by calling their base explicitly. Assume the following hierarchy:
Creature
/ \
Swimmer Flier
\ /
Duck
Which corresponds to
class Creature
{
public:
virtual void print()
{
std::cout << "I'm a creature" << std::endl;
}
};
class Swimmer : public virtual Creature
{
public:
void print()
{
Creature::print();
std::cout << "I can swim" << std::endl;
}
};
class Flier : public virtual Creature
{
public:
void print()
{
Creature::print();
std::cout << "I can fly" << std::endl;
}
};
class Duck : public Flier, public Swimmer
{
public:
void print()
{
Flier::print();
Swimmer::print();
std::cout << "I'm a duck" << std::endl;
}
};
Now this presents a problem - calling the duck's print method calls its respective base methods, all of which in turn call the Creature::print() method, so it ends up being called twice-
I'm a creature
I can fly
I'm a creature
I can swim
I'm a duck
I would like to find a way to make sure the base method is called only once. Something similar to the way virtual inheritance works (calling the base constructor on the first call, then only assigning a pointer to it on successive calls from other derived classes).
Is there some built-in way to do this or do we need to resort to implementing one ourselves?
If so, how would you approach this?
The question isn't specific to printing. I wondered if there's a mechanism for extending base methods and functionality while keeping the call order and avoiding the diamond problem.
I understand now that the most prominent solution would be to add helper methods, but I just wondered if there's a "cleaner" way.
Most likely this is a XY problem. But ... just don't call it twice.
#include <iostream>
class Creature
{
public:
virtual void identify()
{
std::cout << "I'm a creature" << std::endl;
}
};
class Swimmer : public virtual Creature
{
public:
virtual void identify() override
{
Creature::identify();
tell_ability();
std::cout << "I'm a swimmer\n";
}
virtual void tell_ability()
{
std::cout << "I can swim\n";
}
};
class Flier : public virtual Creature
{
public:
virtual void identify() override
{
Creature::identify();
tell_ability();
std::cout << "I'm a flier\n";
}
virtual void tell_ability()
{
std::cout << "I can fly\n";
}
};
class Duck : public Flier, public Swimmer
{
public:
virtual void tell_ability() override
{
Flier::tell_ability();
Swimmer::tell_ability();
}
virtual void identify() override
{
Creature::identify();
tell_ability();
std::cout << "I'm a duck\n";
}
};
int main()
{
Creature c;
c.identify();
std::cout << "------------------\n";
Swimmer s;
s.identify();
std::cout << "------------------\n";
Flier f;
f.identify();
std::cout << "------------------\n";
Duck d;
d.identify();
std::cout << "------------------\n";
}
Output:
I'm a creature
------------------
I'm a creature
I can swim
I'm a swimmer
------------------
I'm a creature
I can fly
I'm a flier
------------------
I'm a creature
I can fly
I can swim
I'm a duck
------------------
We can let the base class keep track of the attributes:
#include <iostream>
#include <string>
#include <vector>
using namespace std::string_literals;
class Creature
{
public:
std::string const attribute{"I'm a creature"s};
std::vector<std::string> attributes{attribute};
virtual void print()
{
for (auto& i : attributes)
std::cout << i << std::endl;
}
};
class Swimmer : public virtual Creature
{
public:
Swimmer() { attributes.push_back(attribute); }
std::string const attribute{"I can swim"s};
};
class Flier : public virtual Creature
{
public:
Flier() { attributes.push_back(attribute); }
std::string const attribute{"I can fly"s};
};
class Duck : public Flier, public Swimmer
{
public:
Duck() { attributes.push_back(attribute); }
std::string const attribute{"I'm a duck"s};
};
int main()
{
Duck d;
d.print();
}
Likewise, if it is not just printing we're after, but rather the function calls, then we could let the base class keep track of the functions:
#include <iostream>
#include <functional>
#include <vector>
class Creature
{
public:
std::vector<std::function<void()>> print_functions{[this] {Creature::print_this(); }};
virtual void print_this()
{
std::cout << "I'm a creature" << std::endl;
}
void print()
{
for (auto& f : print_functions)
f();
}
};
class Swimmer : public virtual Creature
{
public:
Swimmer() { print_functions.push_back([this] {Swimmer::print_this(); }); }
void print_this()
{
std::cout << "I can swim" << std::endl;
}
};
class Flier : public virtual Creature
{
public:
Flier() { print_functions.push_back([this] {Flier::print_this(); }); }
void print_this()
{
std::cout << "I can fly" << std::endl;
}
};
class Duck : public Flier, public Swimmer
{
public:
Duck() { print_functions.push_back([this] {Duck::print_this(); }); }
void print_this()
{
std::cout << "I'm a duck" << std::endl;
}
};
int main()
{
Duck d;
d.print();
}
An easy way is to create a bunch of helper classes that mimick the inheritance structure of your main hierarchy and do all the printing in their constructors.
struct CreaturePrinter {
CreaturePrinter() {
std::cout << "I'm a creature\n";
}
};
struct FlierPrinter: virtual CreaturePrinter ...
struct SwimmerPrinter: virtual CreaturePrinter ...
struct DuckPrinter: FlierPrinter, SwimmerPrinter ...
Then each print method in the main hierarchy just creates the corresponding helper class. No manual chaining.
For maintainability you can make each printer class nested in its corresponding main class.
Naturally in most real world cases you want to pass a reference to the main object as an argument to the constructor of its helper.
Your explicit calls to the print methods form the crux of the issue.
One way round this would be to drop the print calls, and replace them with say
void queue(std::set<std::string>& data)
and you accumulate the print messages into the set. Then it doesn't matter those functions in the hierarchy get called more than once.
You then implement the printing of the set in a single method in Creature.
If you want to preserve the order of printing, then you'd need to replace the set with another container that respects the order of insertion and rejects duplicates.
If you want that middle class method, do not call the base class method. The easiest and simplest way is to extract extra methods, and then reimplementing Print is easy.
class Creature
{
public:
virtual void print()
{
std::cout << "I'm a creature" << std::endl;
}
};
class Swimmer : public virtual Creature
{
public:
void print()
{
Creature::print();
detailPrint();
}
void detailPrint()
{
std::cout << "I can swim" << std::endl;
}
};
class Flier : public virtual Creature
{
public:
void print()
{
Creature::print();
detailPrint();
}
void detailPrint()
{
std::cout << "I can fly" << std::endl;
}
};
class Duck : public Flier, public Swimmer
{
public:
void print()
{
Creature::Print();
Flier::detailPrint();
Swimmer::detailPrint();
detailPrint();
}
void detailPrint()
{
std::cout << "I'm a duck" << std::endl;
}
};
Without details what is your actual problem is, it hard to come up with a better solution.
Use:
template<typename Base, typename Derived>
bool is_dominant_descendant(Derived * x) {
return std::abs(
std::distance(
static_cast<char*>(static_cast<void*>(x)),
static_cast<char*>(static_cast<void*>(dynamic_cast<Base*>(x)))
)
) <= sizeof(Derived);
};
class Creature
{
public:
virtual void print()
{
std::cout << "I'm a creature" << std::endl;
}
};
class Walker : public virtual Creature
{
public:
void print()
{
if (is_dominant_descendant<Creature>(this))
Creature::print();
std::cout << "I can walk" << std::endl;
}
};
class Swimmer : public virtual Creature
{
public:
void print()
{
if (is_dominant_descendant<Creature>(this))
Creature::print();
std::cout << "I can swim" << std::endl;
}
};
class Flier : public virtual Creature
{
public:
void print()
{
if (is_dominant_descendant<Creature>(this))
Creature::print();
std::cout << "I can fly" << std::endl;
}
};
class Duck : public Flier, public Swimmer, public Walker
{
public:
void print()
{
Walker::print();
Swimmer::print();
Flier::print();
std::cout << "I'm a duck" << std::endl;
}
};
And with Visual Studio 2015 the output is:
I'm a creature
I can walk
I can swim
I can fly
I'm a duck
But is_dominant_descendant does not have a portable definition. I wish it were a standard concept.
You are asking for something like inheritance on a function level that automatically calls the inherited function and just adds more code. Also you want it to be done in a virtual way just like class inheritance. Pseudo syntax:
class Swimmer : public virtual Creature
{
public:
// Virtually inherit from Creature::print and extend it by another line of code
void print() : virtual Creature::print()
{
std::cout << "I can swim" << std::endl;
}
};
class Flier : public virtual Creature
{
public:
// Virtually inherit from Creature::print and extend it by another line of code
void print() : virtual Creature::print()
{
std::cout << "I can fly" << std::endl;
}
};
class Duck : public Flier, public Swimmer
{
public:
// Inherit from both prints. As they were created using "virtual function inheritance",
// this will "mix" them just like in virtual class inheritance
void print() : Flier::print(), Swimmer::print()
{
std::cout << "I'm a duck" << std::endl;
}
};
So the answer to your question
Is there some built-in way to do this?
is no. Something like this does not exist in C++. Also, I'm not aware of any other language that has something like this. But it is an interesting idea...