Hi friends,
I have a function pointer array of void type for some functions with different return types, I want to typecast the return type of function at run time. Any one have idea how to do this ?
Printable View
Hi friends,
I have a function pointer array of void type for some functions with different return types, I want to typecast the return type of function at run time. Any one have idea how to do this ?
What exactly are you trying to solve? It may be the case that proper use of inheritance and polymorphism would be a better solution.
Well this would be the most logical way:
But since you're using void* pointers, you'd have to know what the actual type is.Code:derived_type& var = dynamic_cast<derived_type&>( base_type_var );
Assuming you are not interested in C++ solutions as suggested, really, why not use a struct instead of an array, if the functions have different return types? This is the customary way to solve this type of problem.
How about this obfuscation example:
Output:Code:#include <iostream>
int func1();
double func2();
char func3(int x);
typedef void (*voidfunc)();
voidfunc array[3] = { reinterpret_cast<voidfunc>(func1), reinterpret_cast<voidfunc>(func2),
reinterpret_cast<voidfunc>(func3) };
int func1()
{
return 3;
}
double func2()
{
return 6.7;
}
char func3(int x)
{
return 'a' + static_cast<char>(x);
}
int main()
{
std::cout << reinterpret_cast<int (*)(void)>(array[0])() << std::endl;
std::cout << reinterpret_cast<double (*)(void)>(array[1])() << std::endl;
std::cout << reinterpret_cast<char (*)(int)>(array[2])(6) << std::endl;
std::cout << static_cast<int>(reinterpret_cast<char (*)(int)>(array[1])(11)) << std::endl;
return 0;
}
3
6.7
g
-52
Note that the last line shows how easy it is to make a mistake - it calls a function returning a double with no parameters, but it's got a parameter, and expects a char return.
And if any of my collegues showed me code like this, I would probably throw something hard at him/her.
--
Mats
This code is written for TURBO C++ 3.0 version
Here, all function are of return type int and I have created class Generic for type casting of object at run time , because I will be not knowing which object user is going to call. Like this if the functions are of different return types then how I can type cast it at run time ?Code:#include<iostream.h>
#include<stdio.h>
#include<conio.h>
#define EVENTS 5
#define OBJ_FUN 2
class store
{
int qty;
public: int Fn_stor()
{
cout<<"I'm in Fn_stor function of class store \n";
return 5;
}
int Fn_quant()
{
cout<<"I'm in Fn_quant function of class store \n";
return 0;
}
int Fn_get()
{
cout<<"I'm in Fn_get function of class store \n";
return 6;
}
};
class purc
{
public: int Fn_pur()
{
cout<<"I'm in Fn_pur function of class purc \n";
return 7;
}
int Fn_order()
{
cout<<"I'm in Fn_order function of class purc \n";
return 8;
}
int Fn_amount()
{
cout<<"I'm in Fn_amount function of class purc \n";
return 9;
}
};
class manu
{
public: int Fn_man()
{
cout<<"I'm in Fn_manu function of class manu \n";
return 2;
}
int Fn_Time()
{
cout<<"I'm in Fn_Time function of class manu \n";
return 3;
}
int Fn_work()
{
cout<<"I'm in Fn_work function of class manu \n";
return 4;
}
};
class Generic : public store, public purc, public manu
{
};
void main()
{
store str;
purc prc;
manu mnf;
int class_id,Fn_id;
int (Generic::*pt[3][3])() = {
(&store::Fn_stor,&store::Fn_quant,&store::Fn_get),
(&purc::Fn_pur,&purc::Fn_amount,&purc::Fn_order),
(&manu::Fn_man,&manu::Fn_Time,&manu::Fn_work)
};
clrscr();
enum { C_STOR,C_PURC,C_MANF };
enum { Fn1,Fn2,Fn3 };
void *obj_ptr[] = { &str,&prc,&mnf };
int seq[EVENTS][OBJ_FUN] = {
{C_STOR,Fn2},
{C_PURC,Fn1},
{C_STOR,Fn3},
{C_MANF,Fn1},
{C_PURC,Fn2}
};
for(int counter=0;counter<EVENTS;counter++)
{
class_id = seq[counter][0];
Fn_id = seq[counter][1];
((Generic*)obj_ptr[class_id]->*pt[class_id][Fn_id])();
}
getch();
}
Vinod !!
All three classes appear to have nothing in common. There is nothing generic to speak of concerning them.
I think you are making this more complicated than it should be. Just use normal if-else conditional logic to decide which class to instantiate and use.
I have created Generic class because at run time I need to typecast the object. The Generic class inherited all 3 classes so compiler will do typecasting of object to me at ((Generic*)obj_ptr[class_id]->*pt[class_id][Fn_id])(); line. I think you got it. Like this I want to typecast the return type of function when the functions having different return types
You don't need to typecast at all. You are trying to solve your problem in the wrong way.Quote:
I have created Generic class because at run time I need to typecast the object.
Then how can you call member function without type casting the object ?
If I wan to call member function of store class then I need store class object right ! so that I need to typecast !!!
My point is that there is nothing in common between your classes. Furthermore, with multiple inheritance, your Generic class is a store class, so you actually can use non-private members from the store class directly. There is no typecasting needed.Quote:
Then how can you call member function without type casting the object ?
If I wan to call member function of store class then I need store class object right ! so that I need to typecast !!!
But why bother with multiple inheritance in the first place? Why not just instantiate store objects, purc objects and manu objects when the logic dictates that they are needed?
The typical case is that you have similar, but slightly different functionalit, in the form of polymorphic classes.
Your classes appear to have nothing in common - so why would you actually want to operate on them from a common piece of code in any form.
If you have polymorphic problem, you can solve it by a having virtual functions defined in a base-class, and then inherit that base-class into other, so called derived objects. That way, a function using the base-class can access the functionality of any of the derived classes.
For example:
But if the classes have nothing in common, there is no point in trying to MAKE them common.Code:class vehicle
{
public:
virtual int maxLegalWeight();
virtual int maxWheels();
virtual string poweredBy();
};
class bicycle: public vehicle
{
public:
int maxLegalWeight() { return 200; }
int maxWheels() { return 3; }
string poweredBy() { return "Human power"; }
};
class car: public vehicle
{
public:
int maxLegalWeight() { return 3500; }
int maxWheels() { return 4; }
string poweredBy() { return "Petrol/Diesel engine"; }
};
class steamtrain: public vehicle
{
public:
int maxLegalWeight() { return 200000; }
int maxWheels() { return 500; }
string poweredBy() { return "Steam generated from coal"; }
};
--
Mats
But I'm giving option to user that which object and which function to be called at run time. So user will enter only numbers. If He enters 1,1 then it means store object is calling Fn_stor(). So that I want to create 3 objects to store in function pointer array.
Why do you want the user to do that? What is the common factor for the functions you are going to use?
--
Mats
void main is undefined. Don't use it.
Indentation needs work. It's important so we can read the code. Read http://cpwiki.sf.net/Indentaiton.
Nothing common factor in functions. For Example,in Micrsoft Paint brush user will select the circle object and draw it means he can use any object at any time . If in some situation there are 500 of classes then I need to create 500 objects and I need to write switch case for 500 times for 500 objects. If I code like this then no need to write switch case. The ((Generic*)obj_ptr[class_id]->*pt[class_id][Fn_id])(); line will do all things for me ! right
The commonality in what you described is that the user will select a shape. A circle is a shape. A rectangle is a shape. One can enlarge a circle. One can move a circle. One can enlarge a rectangle. One can move a rectangle.Quote:
For Example,in Micrsoft Paint brush user will select the circle object and draw it means he can use any object at any time .
There is something in common there, and we can say that one can move a shape, and one can enlarge a shape. So with a shape base class, the choice of functions is limited to those public member functions specified in shape, even though there may be many more derived class member functions that override these few shape virtual member functions.
It will not. You do not understand: according to your code, a Generic is a store, a Generic is a purc, and a Generic is a manu. Typecasting is useless.Quote:
If I code like this then no need to write switch case. The ((Generic*)obj_ptr[class_id]->*pt[class_id][Fn_id])(); line will do all things for me ! right
You could do the opposite: create a Generic base class (similiar to the Object class in Java and many other OO languages). But then you still have to use a switch of some sort to typecast.
In other words, if there is no commonality, then you have no choice but to use a massive switch. If there is commonality, you can factor it out into a class hierarchy and use polymorphism.
Well, the circle, square and painbrush can all be implemented as an object with a baseclass of:
But you still need to CREATE a circle object if you want to draw a circle.Code:class basicdrawobject
{
public:
void drawat(int x, int y);
void setColor(int rgb);
...
};
There are ways that you can have a common base object that does the necesary operations based on a small set of public functions, where the internal object has completely different capabilities.
But using the "generic object" like you do is absolutely not the right option.
--
Mats
If I have a Function pointer array of void type and storing few function with different return type. I dont know which function user is going to call at run time, so I need to code in such a way that the compiler should typecast the function return type from void function pointer array.
You can't cast function pointers.
Not function pointer. When I need to call a function from that array first I need to type cast that function to its original return type right.
Sure you can - as shown in the second or third post in this thread - however, it's not a particularly clever idea to do that, and the code is definitely not pretty afterwards.
Vinod: So you are going to end up with a 500 case switch statement just to sort out your 500 different casts - and the code will be completely unreadable. YOU ARE NOT USING THE RIGHT SOLUTION!
--
Mats
So tell me how can I typecast the function return type from pointer function array at run time ?
I did, about post #3 or so in this thread. It doesn't look particularly pretty, and you still need to have your switch statement to make sure that the right function is called with the right return type, so you're not really saving anything - just making the code unreadabale and unmaintainable (and very fragile, as the compiler won't tell you when you get it wrong).
--
Mats
I'll solve this and will be back with my solutions friends. Because Nothing is Impossible in this world.............
Good luck.Quote:
I'll solve this and will be back with my solutions friends.
Getting your code featured on The Daily WTF (a.k.a. Worse Than Failure) would be very possible indeed.Quote:
Because Nothing is Impossible in this world.