PDA

View Full Version : wrapper of methods


mickey
11th August 2008, 01:36
Hello,
I need to use pointer to members and retrieve the value (a double) that these members should return. But I have a compile error:

#include <vector>
class B {
double _mean, _mean2;
enum { cnt = 2 };
public:
double (B::*fptr[cnt])(void) const;
B() {
fptr[0] = &B::getMean;
fptr[1] = &B::getMean2;
}
double getMean() const { return _mean; }
double getMean2() const { return _mean2; }
};

class A {
public:
std::vector<B> _vec;

};
//main.cpp
B objB;
A objA;
double db = objA._vec.at(0).fptr[0]; //here error; doens't B::mean() return a double?


//error:
error C2440: 'initializing' : cannot convert from 'double (__thiscall B::* )(void) const' to 'double'

Maybe i', using it in a wrong way.....how can I do this thing, please?

jacek
11th August 2008, 02:10
You can't use pointer to member without an object, because it doesn't point to a method of particular object, but to a class member.

Why do you need pointer to member here? Can't you overload an operator or use normal method?

mickey
11th August 2008, 08:20
You can't use pointer to member without an object, because it doesn't point to a method of particular object, but to a class member.
Why do you need pointer to member here? Can't you overload an operator or use normal method?
To be sincer, there I attached those simple methods for simplicity; but I need to attach 5 functions a bit more complex. what of these will be called depends from console parameters; then they are fixed at program start; what can be a situation where pointer to functions are needed?
Isn't ................._vec.at(0). an instance of a class? I don't understand.....

Can you give me an example of what you mean with overload an operator for this case?

thanks,

caduel
11th August 2008, 13:03
try calling the function returned:
double db = (objA.*(objA._vec.at(0).fptr[0]))();

(or some similar syntax ;-)

HTH

jacek
12th August 2008, 18:22
Isn't ................._vec.at(0). an instance of a class? I don't understand.....
Yes, it it, but "objA._vec.at(0).fptr[0]" is an expression which returns a pointer to member. It doesn't mean "invoke the method that fptr[0] points to". As caduel wrote you have to use special syntax to invoke that method.

Can you give me an example of what you mean with overload an operator for this case?
The user of your class wants to perform some action depending on integer value. If you make him use pointers to members everywhere the code will be error-prone and unreadable. It is better to hide this inside your class and give your user only a convenient method and an enum:
double db = obj.get( B::GeometricMean );
// or using an operator:
double db = obj[ B::GeometricMean ];

mickey
14th August 2008, 12:46
hello,
I understand the alternative but not why I shouldn't use pointertomembers.
Anyway: What do you suggest for this case? The same?

class A {
public:
trasformData1() { ......}
trasformData2() {..........}
trasformData3() { .....}
//maybe here is better use another enum and one "TrasformData(enum);" ? I mean in the same way below....
//trasFormData1,2,3 here are very different
};
class B {
vector<A> _va;
enum trasf { trasf1, trasf2, trasf3; }
public:
void trasform( trasf n) {
switch (n) {
case trasf1 :
//loop on _va and call "_va.trasformData1();"
break;
case trasf2 : "call _va.trasformData2();" break;
case trasf3 :"call _va.trasformData3();" break;
default: exit(-1) //error
};
}
};
//main.cpp
B b;
//fill the vector
//the type of trasformation is chose at command line
b.trasform(B::Trasf1);

jacek
14th August 2008, 20:51
why I shouldn't use pointertomembers.
They're ugly, so if you want ot use them, hide them inside the class.

Anyway: What do you suggest for this case? The same?
How about this?

TransformationFactory::TransformationFactory()
{
transformations[ SomeTransformation ] = new SomeTransformation();
...
}

const Transformation * TransformationFactory::get( TransformationType type )
{
return transformations[ type ];
}

...

transformedVector = factory.get( SomeTransformation )->transform( originalVector );

mickey
15th August 2008, 10:42
How about this?
TransformationFactory::TransformationFactory()
{
transformations[ SomeTransformation ] = new SomeTransformation();
...
}
const Transformation * TransformationFactory::get( TransformationType type )
{
return transformations[ type ];
}
transformedVector = factory.get( SomeTransformation )->transform( originalVector );
Sorry, but I don't understand your example. My trasformation1,2,3 inside A are methods and not object (the do a normalization of the data).....maybe you understood they're objects? Isn't this a "pointer to member" way? I thought that you didn't suggest to use pointer to member..

jacek
15th August 2008, 16:33
My trasformation1,2,3 inside A are methods and not object (the do a normalization of the data).....
Yes and my proposition is to change them into objects.

Isn't this a "pointer to member" way? I thought that you didn't suggest to use pointer to member..
It's very similar, but you can avoid that ugly syntax. Pointers to members will be OK too if you hide them behind some nice interface.