Pointer to members [closed]
In following code consider the statement :- "int B::*bpm;"
class B
{
public :
int bi;
};
class D : public B
{
};
int main()
{
D obj;
int B::*bpm;
bpm = &B::bi;
obj.*bpm = 1;
return 0;
}
*When to use "Pointer to members" in design/code to improve my design/coding practice. **
An example from STL may help.
Talking about design/coding practice then, to me, it's not a good design to use a "pointer to member" to access your members which are anyway public and can be accessed in more obvious ways.
Sometimes pointers to member can be used to avoid code duplication when a similar functionality is required for multiple members. An alternative is to use enum to identify the members and store them as array instead.
struct Foo
{
float a;
float b;
};
void Interpolate(const Foo &x, const Foo &y, float f, int Foo::*member)
{
return x.*member*(1-f)+y.*member*f;
}
int main()
{
Foo x,y;
float ia = Interpolate(x,y,0.5,&Foo::a);
float ib = Interpolate(x,y,0.5,&Foo::b);
}
This is just sample, the the interpolate is short and simple, but once a similar functionality is complex, this can be really beneficial.
Pointer to members have similar uses than pointers to functions. When you need them (very rarely in practice), you'll know it.
One possible use case I encountered before is to specialize an algorithm on some behavior, with templates, with the only goal of not repeating oneself:
struct foo
{
double f1(double);
...
double fn(double);
template <double (foo::*)(double)> double some_algorithm(...);
};
then you use a.some_algorithm<a::&fi>(...)
.
I think you can see the power of pointers to member types if you check out Stroustrup's example:
class Interface {
public:
virtual start() = 0;
virtual stop() = 0;
virtual pause() = 0;
virtual resume() = 0;
virtual ~Interface() { }
}
typedef void (Interface::*P_MEM) (); // pointer to member type
map<string, Interface*> variable;
map<string, P_MEM> operation;
void call_member( string var, string oper )
{
(variable[var]->*operation[oper])(); // var.oper()
}
This allows for dynamic access of a function, or variable.
- You can also use it in a factory of a class, to set the behaviour.
How else would you set the behaviour of a certain algorithm ( see Alexandre's example )?
- You can write a behaviour class, but then you'd have to create one class for each function, and yet another interface for all classes, so that your algorithm calls that. Isn't it a waste if you don't have any data in the classes ?
Pointer to members can be useful for intrusive lists
template<typename N, N *N::*nextp>
class LinkedList {
public:
LinkedList()
:head(0)
{ }
void add(N *item) {
item->*nextp = head;
head = item;
}
N *gethead() { return head; }
private:
N *head;
};
struct Node {
int data;
Node *next;
};
int main() {
LinkedList<Node, &Node::next> n;
Node a1 = { 1 };
Node a2 = { 2 };
n.add(&a2);
n.add(&a1);
// ...
}
I wouldn't worry too much about pointers to members. In >15 years of C++ I have used them once, about ten years ago.
Features already built-in into the language (namely virtual functions) prevent you from having to manually fiddle with member pointers.
精彩评论