Понимание операторов указателя на член - PullRequest
6 голосов
/ 19 декабря 2011

Я скопировал эту программу из учебника по С ++. Что происходит за кулисами?

Ожидаемый результат:

сумма = 30 сум = 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;
}

Ответы [ 3 ]

1 голос
/ 19 декабря 2011

Взгляните на Указатель на данные класса . А из-за ошибки -> * - оператор, между ними нельзя ставить пробел.

1 голос
/ 19 декабря 2011

iammilind держу пари на ошибку; op-> *pf необходимо изменить, чтобы у вас был ->* вместе как один оператор - указатель на член оператора (не удалось найти лучшую ссылку). Пробел в op ->* pf совершенно действителен.

То же самое для чего-то вроде i++; ++ является одним оператором и приведет к ошибке, если вы попытаетесь получить i+ +.

Теперь за то, что он делает. Примером является указатель на функцию-член . pf объявляется как функция-член class M, которая принимает два int аргумента с типом возврата void. Он инициализируется так, чтобы указывать на функцию M::set_xy.

Внутри main:

  • n имеет тип M, поэтому, чтобы использовать pf для вызова set_xy из n, вы должны использовать оператор .*: (n.*pf)(10, 20);. Это эквивалентно n.set_xy(10, 20);.

  • Поскольку op имеет тип M* (указатель на объект M), вам нужно будет использовать оператор ->* и вызвать функцию, указанную pf, следующим образом: (op->*pf)(30, 40);, что эквивалентно op->set_xy(30, 40);

Внутри sum:

  • Примеры являются просто указателями на переменные-члены / экземпляры, а не на функции-члены. Это просто демонстрация того, как вы сложите m.x и m.y, используя указатели этих типов.
1 голос
/ 19 декабря 2011

Проблема в том, что лишние пробелы в op-> *pf:

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

Я думаю, что @fefe, вероятно, сказал причину в комментарии.->* - это один оператор, аналогичный .*.Таким образом, если эти 2 разделены, то это приведет к другому синтаксису, что приведет к ошибке компиляции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...