views:

148

answers:

7

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. *

+1  A: 

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.

Hemant
A: 

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.

sbi
You never used MFC then.
Alexandre C.
@Alexandre: No, I didn't. And I'm glad about that. `:)`
sbi
@sbi: you're just lucky
Alexandre C.
@Alexandre: I'm not sure. I might not have turned down a job offer only because it would have been an MFC job, but that _would_ have had a _very_ strong negative influence on the decision making process. `:)`
sbi
@sbi: MFC is on its way to being eradicated now, so you should be pretty safe. I _do_ hate MFC and ATL, from the heart of my heart, but I got hired to do interesting math, but with MFC and COM layers everywhere...
Alexandre C.
@Alexandre: I feel with you. Here, have a virtual beer! `:)`
sbi
+1  A: 

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.

Suma
@Suma: Is it a good idea to have some other entity (namespace function) in the system working on (supposedly private) data of 'Foo'?
Chubsdad
This is just a concept example. In practice either Interpolate would be a member function, or you would access a and b via member functions and provide pointers to member functions instead.
Suma
+3  A: 

An example from STL may help.

Chubsdad
yep, STL really lacks this functionality built-in. Using algorithms on sequences of first elements of pairs for instance is cumbersome.
Alexandre C.
+1  A: 

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>(...).

Alexandre C.
+1  A: 

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 ?
Grim Fandango
+1  A: 

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);
  // ...
}
Johannes Schaub - litb