C++11 Call virtual member function - c++11

I`m trying to implement something like this using C++11.
class Proto{
public:
virtual void fu() = 0;
};
class Impl: public Proto{
public:
void fu();
};
void Impl::fu(){
LOG_INFO("im fu");
}
class Inv{
public:
void useFu(void (Proto::*)());
};
void Inv::useFu(void (Proto::*fu)()){
//fu();
};
void main(){
Impl impl;
Inv inv;
//inv.useFu(impl.fu);
}
useFu(void (Proto::*)()) must be declared in this way because, fu() uses some specific to Proto functionality's
I have two places were things going wrong.
First is fu() call itself and second how to pass fu as parameter inv.useFu(impl.fu).
Edit after bipll answer
The suggested usage of inv.useFu() solves the second problem of my question.
inv.useFu(static_cast<void (Proto::*)(void)>(&Impl::fu));
But I still need to call fu as a pointer to member function;

The way your useFu is declared now, it should be called as
inv.useFu(static_cast<void (Proto::*)(void)>(&Impl::fu));
But I guess that's not what you wanted. It should rather be
template<class F> void useFu(F &&f) { std::invoke(std::forward<F>(f)); }
or simply
void useFu(std::function<void()> f) { std::invoke(std::move(f)); }
and called as
useFu([&]{ impl.fu(); });
(Rather than using a lambda you can bind the method to the object with std::bind in the latter call but almost nobody ever does that.)

Related

Gtest and gmock in below code snippet though error

How to achieve gtest or gmock for the private and protected member function. I am new to gtest and gmock. Below is the code for which i need to do gtest or gmock along with my attemp.
constexpr static char _session[]{"S_ID"};
typedef struct {
int session;
} Session;
typedef std::function<void(const Session &)> SessionCallback_t;
class Service : public ParentService {
public:
Service();
void registerCallback(const SessionCallback_t & callback);
protected:
virtual void notifyHandler(const Json::Value & data) override;
virtual void notifyState();
private:
Session mSession;
SessionCallback_t mCallback;
void jsonParse(const Json::Value & json_data);
};
My Attemp which doesn't compile
class TestService : public Service {
public:
TestService(): Service() {
}
bool registerCallback(const SessionCallback_t & cb) {
// how to achive this?
}
};
class MyTestService : public ::testing::Test {
protected:
virtual void SetUp() {
}
virtual void TearDown() {
}
};
TEST_F(MyTestService , registerCallbackTest) {
TestService service;
EXPECT_TRUE(service.registerCallback(SessionCallback_t));
}
I am stuck with the below interface
1.registerCallback()
2.notifyHandler()
3.notifyState()
4.jsonParse()
Please though some light to proceed further.
Welcome to Stack Overflow!
First, let me recommend this recent episode of CppCast on Designing for Testing. The podcast notes that if you find your code is hard to test, it means it is too tightly coupled and is thus poorly designed.
It also (rightly, IMHO) recommends that you test only public functions. If you find yourself needing to test the private functions, you should probably refactor the code.
One way to do that is to break your code into multiple classes with the public functions you want to test. Then, your composite class can either create and own the class directly (appropriate if it's a basic type with no dependencies or complex resources of its own such as a vector or string class) or can use dependency injection to pass in the dependencies as constructor or method parameters (appropriate for databases, network connections, file systems, etc.).
Then in testing, you pass in a test double, such as a mocked object or a simplified implementation like an in-memory database instead of an out-of-process database connection, that acts like the object but does what you need in the test situation.
That's the basic advice. In your specific case, it looks like you're trying to override a non-virtual function in your TestService. What are you wanting to test exactly?
I wouldn't expect EXPECT_TRUE(service.registerCallback(SessionCallback_t)); to compile because SessionCallback_t names a type, not an instance of a type, so you can't pass it in. Again, what are you trying to accomplish?
Update to comment:
Mocking requires virtual functions (or duck typing) and dependency injection.
If you just want to test registerCallback(), I suspect you don't need a mock at all. Rather, you need to look at the function's documentation to see what it says it will do -- sometimes called the contract. For instance, what are the preconditions and postconditions of the function? What are the error cases it might encounter? These are what a unit test should cover.
For instance, does it retain only one callback (hint: as written, yes)? What happens when you call it when there is already a callback registered? Does it tolerate default-initialized std::function objects being passed in?
The bigger question is, how do you validate that your test is correct. If you start triggering notifications on your callback, you're venturing beyond the scope of testing this function in isolation. Instead, you could create an accessor class in your test to publicize what is private so you can validate. Still, you can't compare std::function for equality, so the best you can do is to invoke it and check that an expected side effect happens:
class TestService : public Service {
public:
const SessionCallback_t& getCallback() const { return mCallback; }
};
struct TestCallback
{
int mCount = 0;
void operator()( const Session& ) { ++mCount; }
};
Then in your test, you can write a tests like:
TEST_F(MyTestService , Test_registerCallback_BadCallback) {
auto service = TestService{};
EXPECT_THROW( service.registerCallback( SessionCallback_t{} ), std::out_of_range );
}
// Register and check that it's our callback
TEST_F(MyTestService , Test_registerCallback_CallbackSaved) {
auto service = TestService{};
auto callback = TestCallback{};
EXPECT_TRUE( service.registerCallback( callback ) );
EXPECT_EQ( callback.mCount, 0 );
auto actualCallback = service.getCallback();
EXPECT_TRUE( actualCallback );
actualCallback();
EXPECT_EQ( callback.mCount, 1 );
}
TEST_F(MyTestService , Test_registerCallback_CallbackOverwrite) {
auto service = TestService{};
auto callback1 = TestCallback{};
auto callback2 = TestCallback{};
EXPECT_TRUE( service.registerCallback( callback1 ) );
EXPECT_TRUE( service.registerCallback( callback2 ) );
EXPECT_EQ( callback1.mCount, 0 );
EXPECT_EQ( callback2.mCount, 0 );
auto actualCallback = service.getCallback();
EXPECT_TRUE( actualCallback );
actualCallback();
EXPECT_EQ( callback1.mCount, 0 );
EXPECT_EQ( callback2.mCount, 1 );
}

How to use a templated google benchmark fixture with custom arguments correctly?

I want to modify a templated google benchmark (with custom arguments) to run with a test fixture class, but don't know if this is really possible and if so, how the correct syntax is.
Just adding the fixture class doesn't seem to be enough.
static void CustomArguments(benchmark::internal::Benchmark* b) {
// define I, J
for (auto i : I)
{
for (auto j : J)
b->Args({i, j});
}
}
template<typename my_type>
class My_Fixture : public benchmark::Fixture
{
protected:
void SetUp(const ::benchmark::State& state) { ...}
virtual void TearDown() { ...}
};
template <typename any_type>
static void insert(benchmark::State& state)
{
for (auto _ : state)
{ ...}
}
BENCHMARK_TEMPLATE_F(My_Fixture, insert, my_type)->Apply(CustomArguments);
BENCHMARK_MAIN();
The compiler complains about the before-last code line
error: expected initializer before '->' token, but also fails to find the variable declarations from the fixture inside the test. This might be a consequence or an additional error. Do I need to register the fixture additionally? The example is running perfectly without fixture.
You'll need to use a slightly less convenient registration macro:
BENCHMARK_TEMPLATE_DEFINE_F defines the templated benchmark with the fixture. Then BENCHMARK_REGISTER_F can be used to register the benchmark, and that is where you'd add the ->Apply(CustomArguments) call.
See here for an example.

Inferencing the typename of 'this' in a virtual method

I am aware of the lack of reflection and basic template mechanics in C++ so the example below can't work. But maybe there's a hack to achieve the intended purpose in another way?
template <typename OwnerClass>
struct Template
{
OwnerClass *owner;
};
struct Base
{
virtual void funct ()
{
Template <decltype(*this)> temp;
// ...
}
};
struct Derived : public Base
{
void whatever ()
{
// supposed to infer this class and use Template<Derived>
// any chance some macro or constexpr magic could help?
funct();
}
};
In the example, Derived::whatever() calls virtual method Base::funct() and wants it to pass its own class name (Derived) to a template. The compiler complains "'owner' declared as a pointer to a reference of type 'Base &'". Not only does decltype(*this) not provide a typename but a reference, the compiler also can't know in advance that funct is called from Derived, which would require funct() to be made a template.
If funct() was a template however, each derived class needs to pass its own name with every call, which is pretty verbose and redundant.
Is there any hack to get around this limitation and make calls to funct() infer the typename of the calling class? Maybe constexpr or macros to help the compiler infer the correct type and reduce verbosity in derived classes?
You should use CRTP Pattern (Curiously Recurring Template Pattern) for inheritance.
Define a base class:
struct CBase {
virtual ~CBase() {}
virtual void function() = 0;
};
Define a prepared to CRTP class:
template<typename T>
struct CBaseCrtp : public CBase {
virtual ~CBaseCrtp() {}
void function() override {
using DerivedType = T;
//do stuff
}
};
Inherit from the CRTP one:
struct Derived : public CBaseCrtp<Derived> {
};
It should work. The only way to know the Derived type is to give it to the base!
Currently, this can't be done. Base is a Base and nothing else at the time Template <decltype(*this)> is instantiated. You are trying to mix the static type system for an inheritance hierarchy inherently not resolved before runtime. This very same mechanism is the reason for not calling virtual member functions of an object during its construction.
At some point, this limitation might change in the future. One step towards this is demonstrated in the Deducing this proposal.

A delegate to a virtual method where does it point to (base/derived)?

I recently started using C++/Cli for wrapping purposes.
Now I'm at a point where I've to know more about the internals.
Consider the following code:
Header file (ignoring .NET namespaces for this example):
public ref class BaseyClass
{
protected:
delegate void TestMethodDelegate(); // TestMethod delegate
BaseyClass(); // constructor
virtual void TestMethod(); // member: method
GCHandle _testMethodHandle; // member: method handle
};
CPP file (ignoring .NET namespaces for this example):
BaseyClass::BaseyClass()
{
_testMethodHandle
= GCHandle::Alloc(
gcnew TestMethodDelegate(this, &BaseyClass::TestMethod));
}
void TestMethod()
{
}
Eventually this class will be used as base class (for a DerivedClass) later and the method "TestMethod()" gets overridden and called from unmanaged code through the delegate pointer.
Now the question: Which method will be referenced by the delegate?
BaseyClass::TestMethod();
or
DerivedClass::TestMethod();
Personally I think the "BaseyClass::TestMethod()" will be referenced by the delegate because even when it's overridden, the delegate points to the (base-)address of BaseyClass. Hence a DerivedClass cannot override the "TestMethod" and use the delegate from BaseyClass.
I just want to be sure. Thanks for your comments and enlightment.
The delegate will be a reference to the derived class's TestMethod. Even though you're passing &BaseyClass::TestMethod, that's a virtual method, you're also passing this, which is the derived type, and both of those are taken into account when the delegate is created.
Other notes:
TestMethodDelegate doesn't need to be inside the class definition. The more standard way is to have the delegate outside of the class, just in the namespace. (Or use the existing built-in one, Action.)
You don't need to GCHandle::Alloc (I assume that's what you meant by Allow). Instead, declare _testMethodHandle as TestMethodDelegate^ (or Action^). In general, you shouldn't need to deal with GCHandle unless you're interfacing with unmanaged code, and this code is all managed.
Here's my test code:
public ref class BaseyClass
{
public:
BaseyClass() { this->_testMethodHandle = gcnew Action(this, &BaseyClass::TestMethod); }
virtual void TestMethod() { Debug::WriteLine("BaseyClass::TestMethod"); }
Action^ _testMethodHandle;
};
public ref class DerivedClass : BaseyClass
{
public:
virtual void TestMethod() override { Debug::WriteLine("DerivedClass::TestMethod"); }
};
int main(array<System::String ^> ^args)
{
BaseyClass^ base = gcnew DerivedClass();
base->_testMethodHandle();
return 0;
}
Output:
DerivedClass::TestMethod

D Analogue to C++ member-function-pointers, not necessarily delegates

I have been learning D, and am in particular very excited for it's Generic programming capabilities. Delegates are wonderful, and apparently they have completely replaced member-function-pointers, so I was stuck when I wanted to implement something like the following:
template <typename T>
void DispatchMethodForAll(std::vector<T*> & container, void (T::* func)(void))
{
for(typename std::vector<T*>::iterator it = container.begin(); it != container.end(); ++it)
(*it)->*func();
}
According to what I have learned of function pointers and delegates in D, is that neither of them can do this, since function pointers can only be declared for global functions, and delegates have to be bound to an object, there is no "partial delegate" that I can find. As seen here, I cannot use a delegate, since there is no single object that can be bound to the method that is to be called.
I know that I could do it with mixins, and essentially make it a macro. However this really doesn't sound D-like, and I figured there should be "The correct way"
You could still use a delegate here.
void DispatchMethodForAll(T)(T*[] container, void delegate(T*) action)
{
foreach (it; container)
action(it);
}
...
DispatchMethodForAll(container, (Foo* foo) { foo.func(); });
Example: http://www.ideone.com/9HUJa
you can take a page out of the std.algorithm to find out how it does that
void DispatchMethodForAll(alias func, T)(T container)
{
alias unaryFun!func _func
foreach (it; container)
_func(it);
}
btw a delegate can be bound to a struct and the compiler can create a custom struct from local (stack allocated) variables and define a delegate on that
this happens with
void foo(){
int[] array;
int i=0;
void bar(int a){
i+=a;
}
void DispatchMethodForAll(&bar)(array);
writeln(i);//prints the sum of array
}
bar is a delegate bound to a struct with (at least) a member i of type int of which the local variable i is an alias

Resources