6

I copied this program from a c++ practice book. What's going on behind the scenes?

The expected output is:

sum=30 sum=70

#include<iostream>
using namespace std;

class M
{
    int x;
    int y;
public:
    void set_xy(int a, int b)
    {
        x=a;
        y=b;
    }
    friend int sum(M m);
};

int sum (M m);
//so far so good, problem begins from here. what's happening after here?
{                               
    int M ::*px = &M ::x;
    int M ::*py = &M ::y;
    M *pm =&m;
    int s= m.*px+ pm->*py;
    return s;
}

int main()
{
    M n;
    void (M :: *pf)(int, int) = &M ::set_xy;
    (n.*pf)(10, 20);
    cout <<"sum=" << sum(n) << endl;

    M *op= &n;
    (op-> *pf)(30,40);
    cout << "sum=" << sum(n)<< endl;

    cin.ignore();
    getchar();
    return 0;
}
AusCBloke
  • 18,014
  • 6
  • 40
  • 44

3 Answers3

1

The problem is because of extra whitespace at op-> *pf:

 (op->*pf)(30,40);  // ok

I think @fefe has probably said the reason in comment. ->* is a single operator, similar to .*. So, if those 2 are separated, then it will result in different syntax, which gives compiler error.

iammilind
  • 68,093
  • 33
  • 169
  • 336
  • i read somewhere that c++ does not bothers about white spaces. let's try if it works. –  Dec 19 '11 at 06:24
  • 3
    @jeet.mg: the operator is `->*`. You can't put spaces anywhere you like (like `dele te` isn't the same as `delete`) – Mat Dec 19 '11 at 06:25
  • that problem is solved. can someone explain it's working please ? –  Dec 19 '11 at 06:32
  • @jeet.mg, that's a different question. You may have to 1st look at your code and if not understandable then you can post another question. – iammilind Dec 19 '11 at 06:34
1

Take a look at Pointer to class data. And for the error, ->* is an operator, you can't put a space between them.

Community
  • 1
  • 1
Shawnone
  • 850
  • 5
  • 17
1

iammilind bet me to the error; op-> *pf must be changed so that you have ->* together as a single operator - a pointer to member operator (couldn't find a better link). The whitespace in op ->* pf is perfectly valid.

That's the same for something like i++; ++ is a single operator and will cause an error if you try and have i+ +.

Now for what it's doing. The example is of a pointer to a member function. pf is being declared as a member function of class M, that takes two int arguments with a void return type. It's being initialized to point to the M::set_xy function.

Inside main:

  • n is of type M, therefore in order to use pf to call set_xy of n you'd use the .* operator: (n.*pf)(10, 20);. That's equivalent to n.set_xy(10, 20);.

  • Since op is of type M* (a pointer to an M object), you'll need to use the ->* operator and call the function pointed to by pf as: (op->*pf)(30, 40);, which is equivalent to op->set_xy(30, 40);

Inside sum:

  • The examples are simply of pointers to member/instance variables, as opposed to member functions. It's simply demonstrating how you would add together m.x and m.y using those types of pointers.
Community
  • 1
  • 1
AusCBloke
  • 18,014
  • 6
  • 40
  • 44