FuncPtrTab to Method - c++

I'm having a hard time trying to make this work. I'm trying to execute a method
stocked in a method pointer tab.
here is my example :
void class1::fct1();
void Class1::fct2();
void Class1::manageFct()
{
static const void (*ptrFuncTab)[] = {
&Class1::fct1,
&Class1::fct2
};
opCode = 0;
ptrFunctab[opCode](); //==> call Cpu::fct1()
}
i understand that i have to put the instance in which i want to apply
the fct pointed. But how ?
Does anyone knows what i'm doing wrong ?
Thanks,
Cuva

Do this:
typedef void (Class1::*MemFn)();
static const MemFn ptrFuncTab[] = {
&Class1::fct1,
&Class1::fct2
};
What you were using is called pointer-to-function; what I'm using is called pointer-to-member-function. And they're not the same thing.
Use this function table as:
Class1 c;
(c.*ptrFuncTab[0])();
Or if you want to use pointer, then
Class1 *pC = new Class1();
(pC->*ptrFuncTab[0])();

Once you edit like Nawaz said, you call a function in the table like this:
Class1* ptr = new Class1();
(ptr->*ptrFuncTab[opCode])();
for a pointer, and like this:
Class1 ref;
(ref.*ptrFuncTab[opCode])();
for a reference.

Related

Overload -> arrow operator in shared_ptr<interface> instance with no pure virtual destructor in interface

I'm trying to overload the -> operator to eventually execute something along the lines:
MyInterface *myInstance = (MyInterface *)(new A());
myInstance->Toggle(); //this works wonderfully
std::shared_ptr<Wrapper<MyInterface>> sharedPtrWrapper = std::make_shared<Wrapper<MyInterface>>(myInstance);
//the next line doesn't compile, I would like to achieve something like this, but even
//sharedPtrWrapper.get()->Toggle();
//would be nice to achieve, is this possible?
sharedPtrWrapper->Toggle();
//this works:
sharedPtrWrapper->operator->()->Toggle();
Note: I have no control over MyInterface, cannot implement the pure virtual destructor.
Here is what I tried (the below code runs):
#import <memory>
#import <iostream>
struct MyInterface {
virtual bool Toggle() = 0;
};
class A : public MyInterface {
public:
bool Toggle() {
stateEnabled = !stateEnabled;
std::cout<<"current state " << stateEnabled << std::endl;
return true;
}
private:
bool stateEnabled = false;
};
template <typename T>
class Wrapper {
private:
T *unsafePointer = nullptr;
public:
Wrapper<T>()
{ }
T *operator->() const {
return unsafePointer;
}
T *getInner() {
return unsafePointer;
}
Wrapper<T>(T *stuff) {
unsafePointer = stuff;
}
~Wrapper<T>() {}
};
int main(int argc, const char * argv[]) {
MyInterface *myInstance = (MyInterface *)(new A());
myInstance->Toggle();
Wrapper<MyInterface> wrapperS(myInstance);
wrapperS->Toggle();
std::shared_ptr<Wrapper<MyInterface>> sharedPtrWrapper = std::make_shared<Wrapper<MyInterface>>(myInstance);
sharedPtrWrapper->operator->()->Toggle();
sharedPtrWrapper.operator->()->operator->()->Toggle();
sharedPtrWrapper.get()->operator->()->Toggle();
(*sharedPtrWrapper).operator->()->Toggle();
return 0;
}
Output:
current state 1
current state 0
current state 1
current state 0
current state 1
current state 0
Program ended with exit code: 0
To reiterate:
This code doesn't compile:
sharedPtrWrapper->Toggle();
How to make it compile?
Edit : I'm using a wrapper because I have no control over the MyInterface, I get it from a library, also shared_ptr<MyInterface> mySharedPointer = std::make_shared<MyInterface>(myInstance); doesn't compile, because of the missing pure virtual destructor from the above mentioned interface.
Edit2: Example library usage in pseudocode:
void firstcallbackFromLib(Framework *framework) {
MyInterface *myInstance = framework->getInstance();
{
Wrapper<MyInterface> wrapperS(myInstance);
std::shared_ptr<Wrapper<MyInterface>> sharedPtrWrapper = std::make_shared<Wrapper<MyInterface>>(wrapperS);
//assign sharedPtrWrapper and framework to static instances
}
}
void myFunction() {
sharedPtrWrapper->Toggle(); //this doesn't work, this is what i'm trying to achieve
sharedPtrWrapper->operator->()->Toggle(); //this ugly thing works
}
void lastUninitCallbackFromLibrary() {
MyInterface *p = sharedPtrWrapper.get()->getInner();
framework->releaseInterface(p);
//etc
}
The problem is, that shared_ptr behaves like a pointer and Wrapper does that as well. In summary, you have code that behaves like a pointer to a pointer. In short, you could call (*sharedPtrWrapper)->Toggle(); instead of the abomination sharedPtrWrapper->operator->()->Toggle();.
Careful though: It's unclear what all this is supposed to achieve, because the example code is just an abstraction of your actual code. So, maybe it would just be more elegant to put a forwarding Toggle() method into class Wrapper, but that's impossible to tell with the info provided here.
I am confused about the question. Why wrapper class that does nothing?
If you want to put a class inside shared pointer yet do something uncommon at destruction: like, calling dll's function that performs the destruction, do some preprocessing, perform file closure instead of delete, or do nothing at all if that's what you want. Then you can simply specify it at shared pointer instantiation:
https://en.cppreference.com/w/cpp/memory/shared_ptr/shared_ptr - see construction option 5.
You don't need your wrapper at all.
shared_ptr<MyInterface> mySharedPointer = std::make_shared<MyInterface>();
wont work because MyInterface is an abstract class. But, just like you can do
MyInterface *myInstance = new A();
To have a MyInterface * that points to a concrete derived object, you can use
std::shared_ptr<MyInterface> sharedPtr = std::make_shared<A>();
To get a std::shared_ptr<MyInterface> that points to a concrete derived object. You can then use sharedPtr to access Toggle like
sharedPtr->Toggle();
You can see that working in this live example
sharedPtrWrapper->Toggle(); doesn't compile because of operator-> chaining rules explained well in this answer. In principle: if your object is NOT a pointer, operator-> is called recursively, if it is a pointer, member access is performed. Now std::shared_ptr has overloaded operator-> to access the raw Wrapper<MyInterface>* pointer kept inside and when it is applied on it, it tries to access Toggle, which does not exist.
For clarity note that this code also will not compile:
Wrapper<MyInterface>* wrapper = new Wrapper<MyInterface>(myInstance);
wrapper->Toggle();
You can do this however:
(*sharedPtrWrapper)->Toggle();
Use:
struct CleanupMyInterface {
SomeTypeFromLib* somePointerFromLib = nullptr;
void operator()( MyInterface* ptr ) const {
if (somePointerFromLib && ptr)
somePointerFromLib->releaseInterface(ptr);
}
};
std::shared_ptr<MyInterface> sharedPtr( CreateAnInstanceOfAFromLibrary(), CleanupMyInterface{somePointerFromLib} );
shared_ptr has type-erased destruction, there is no need for a virtual destructor.

C++ Google Mock SaveArg : how to save a pointer argument

I having difficulty saving a pointer argument that my mock receives.
#define SIZE_OF_DATA
typedef struct {
uint32_t someValue1;
uint16_t someValue2;
// other values here
} LargeStruct;
class SomeClass {
public:
// assume sendData is a generic function where data is actually pointer to a LargeStruct
void sendData(const uint8_t* data, const uint16_t size);
}
class MockClass : public SomeClass {
public:
MOCK_METHOD2(sendData, void(const uint8_t*, const uint16_t));
};
I want to save the first argument to sendData (the pointer) and look at the data it points to (it points to a large struct, so I don't want to copy by value):
TEST(SomeFixture, sendData_checkSentDataIsValid) {
MockClass mock;
const uint8_t *pData;
EXPECT_CALL(mock, sendData(_, SIZE_OF_DATA)).WillOnce(SaveArg<0>(&pData));
// do something here that calls sendData()
// hopefully data should point to the same data that was passed in to the method
LargeStruct *ls = (LargeStruct *)pData;
// now verify that the data is ok...
// some expectations here
EXPECT_EQ(SOMEVALUEIWANT, ls->someValue1);
}
However, the data pointed to by pData is wrong - I think I appear to be saving the pointer value into the struct, rather than saving the pointer.
I think the problem lies in the variable I pass to SaveArg, but I can't seem to get it in a version that compiles and gives me the correct answer. Any pointers please?
I just ran into the same situation, and in my case, I had to make sure that the pointer passed into the equivalent of your sendData() function was not pointing to an automatic variable on the stack. Otherwise, by the time you access the pointer, the contents will have changed. I found that less than helpful, so I decided to define a customized alternative to SaveArg like this:
ACTION_TEMPLATE(SaveSomeValue1,
HAS_1_TEMPLATE_PARAMS(int, k),
AND_1_VALUE_PARAMS(pointer))
{
const void * data = ::std::tr1::get<k>(args);
const LargeStruct* ls = (const LargeStruct *)data;
*pointer = ls->someValue1;
}
You can then use it like this:
uint32_t someValue1;
EXPECT_CALL(mock, sendData(_, SIZE_OF_DATA))
.WillOnce(SaveSomeValue1<0>(&someValue1));
//...
EXPECT_EQ(SOMEVALUEIWANT, someValue1);
You can create one void pointer as a buffer and save argument inside that buffer. After that you should cast the buffer to your large structure.
TEST(SomeFixture, sendData_checkSentDataIsValid) {
MockClass mock;
LargeStruct *ls;
void *buffer;
EXPECT_CALL(mock, sendData(_, SIZE_OF_DATA))
.WillOnce(SaveArg<0>(&buffer));
// do something here that calls sendData()
ls = static_cast<LargeStruct *>(buffer);
EXPECT_EQ(SOMEVALUEIWANT, ls->someValue1);
}

passing variable using void *

I was writing an interface(using FLTK but this doesn't matter). I made a button and its callback function. In this callback function I need to use data in a variable outside the callback function(which is Myclass mc in the code). The code looks like the following (I didn't paste the unnecessary parts):
class Myclass
{
...
}
void button_callback( Fl_Widget* o, void* data)
{
Fl_Button* button=(Fl_Button*)o;
Myclass *a;
a=data;
a->MyMemberFunction();
}
int main()
{
Myclass mc;
...
Fl_Button button( 10, 150, 70, 30, "A button" );
button.callback( button_callback,&mc );
...
}
However at the place of "a=data;" I got an error saying void * cannot be assigned to Myclass *, what should I do?
Many thanks!
Assuming that the data coming in through the void* is a pointer to Myclass, you need to add a reinterpret_cast from the void*, like this:
Myclass *a = reinterpret_cast<Myclass*>(data);
This will tell the compiler that you know for sure that the data is a pointer to Myclass, letting you call MyMemberFunction() through that pointer.
you need to use any kind of type casting:
here is C variant:
Myclass *a = (Myclass*)data;
here is C++ variant:
Myclass* a = reinterpret_cast<Myclass*>(data);

Why can't I set a value inside of this class?

I have a class:
class SendData
{
public:
SendData(int SendAMsg(int foo, unsigned char *bar, int length), int number)
{
m_nDefinePos = 0;
m_nOtherStuffDefinedAs =0;
}
void somestuffhere();
void ClearDefinition();
private:
int aLotOfVariableshere;
int m_nDefinePos;
};
This is the class itself. Then some stuff is called:
SendData* m_pData;
m_pData->ClearDefinition();
Which now calls this one:
void SendData::ClearDefinition()
{
printf("Welcome to Clear Definition Script\n");
m_nDefinePos = 0;
// Some more stuff here
}
Here the code breaks somehow. I get the "Welcome to Clear Definition Script" message in my console, but that's all.
It breaks on m_nDefinePos = 0;. (I did put in another printf command after it, never showed in the console.)
I just don't know why it breaks there and i cant find any error.
SendData* m_pData;
m_pData->ClearDefinition();
This declares a pointer, but doesn't create an object or initialise the pointer to point to anything, so calling a member function via the pointer will go wrong. Perhaps you wanted to create an object:
SendData data(arguments);
data.ClearDefinition();
or perhaps you wanted to initialise the pointer to point an object that already exists:
SendData* m_pData = whatever;

Handling functions with more than one output parameters

How do we handle more than one output parameters in C++.I am beginner in C++ and currently i am trying to write a function A which calls another function B of some other class,Function B consists of 6 parameters in total ,of which three are input parameters and the rest three are output parameters.How can i access all the three output parameters within my function A?I tried to do it in the following way...Can anyone help me to correct my code if i have gone wrong..?Please do help me friends..
class A ::functionA()
{
int in_a=1;
string in_b= "name";
int in_c=3;
int ot_a=0;
int ot_b=0;
string ot_s1=""
ClassB *classB();
classB = classB.functionB(in_a,in_b,in_c,ot_a,ot_b,ot_s1); //is this way correct?
ot_a= ? ;
ot_b=? ;
ot_s1=?
}
can i use something like ot_a=classB.ot_a ?Please help me...
You have got the basic syntax of C++ wrong. ClassB *classB(); does not create any object, it declares a function prototype of function classB which returns ClassB*. To create a object you should do ClassB b; and then use b as you have done. The output variables will be correctly filled up by the function if it is taking its parameter by reference.
For multiple return values, you got generally two choices:
return a struct containing your return values
pass the return values in per reference.
Both examples demonstrated:
// first approach, struct return
struct myReturns{
int int_return;
float float_return;
};
myReturns MyFunc(int param1, char* param2, ...){
// do some stuff with the parameters
myReturns ret;
ret.int_return = 42;
ret.float_return = 13.37f;
return ret;
}
// calling it:
myReturns ret = MyFunc(/*pass your parameters here*/);
int i = ret.int_return;
float f = ret.float_return;
// second approach, out parameters
void MyFunc(int inParam1, char* inParam2, int& outInt, float& outFloat){
// do some stuff with the parameters
outInt = 42;
outFloat = 13.37f;
}
// calling it:
int i;
float f;
MyFunc(/*your parameters here*/,i,f);
// i and f are now changed with the return values
As mentionned in Xeo's answer, you can use return structures or references.
There is another possibility, to use pointers.
Pointers allows you to do one thing : if the function you call can be used to compute multiple informations, but you don't want all of them, you can pass NULL as the value of the pointer so that the function knows it doesn't need to fill these informations.
Of course, the function you call needs to be designed that way, it's not automatic.
void f()
{
type1* p1 = new type1();
type2* p2 = NULL
g(p1, p2);
}
void g(type1* param1, type2* param2)
{
//Do some computation here
if (param1 != NULL)
{
//Do something here to fill param1
}
if (param2 != NULL)
{
//Do something here to fill param2
}
}
But as a general rule, it's better to use references when you can, and pointers when tou have to. If the function doesn't handle the case when a pointer passed to it is NULL, you will end with a crash. References can't be NULL, so they avoid this problem.
Answer is: references.
ClassB *classB();
classB = classB.functionB(in_a,in_b,in_c,ot_a,ot_b,ot_s1);
By looking . operator after classB, I assume that you are thinking classB is an object. No, it is not.
ClassB *classB();
The above statement says - classB() is a function that takes no parameters and return type is a reference to ClassB.
If you can change functionB() then use pointers as parameters. This way you can change the value inside functionB() and they will be changed directly in functionA().