【问题标题】:Understanding Pointer-to-Member operators了解指针成员运算符
【发布时间】:2012-01-23 08:57:45
【问题描述】:

我从一本 c++ 练习书中复制了这个程序。幕后发生了什么?

预期的输出是:

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;
}

【问题讨论】:

  • "->*" 是一个运算符,而不是两个。所以他们不能分开。你不能写“-> *”。
  • 这个问题解决了。有人可以解释一下它的工作原理吗?
  • 移除标签“visual-studio”,因为这不是编译器特有的问题
  • cin.ignore();获取字符();是 Visual Studio 的命令。
  • @jeet.mg,是的命令是针对VS的,但不是编译器错误问题

标签: c++ pointers compiler-errors dereference pointer-to-member


【解决方案1】:

iammilind我赌错了; op-&gt; *pf 必须更改,以便将 -&gt;* 一起作为单个运算符 - pointer to member operator(找不到更好的链接)。 op -&gt;* pf 中的空格完全有效。

对于i++ 之类的内容也是如此; ++ 是单个运算符,如果您尝试使用 i+ +,则会导致错误。

现在看看它在做什么。该示例是一个 指向成员的指针 函数。 pf 被声明为class M 的成员函数,它接受两个int 参数和void 返回类型。它被初始化为指向M::set_xy 函数。

内部main

  • n 的类型为 M,因此要使用 pf 调用 set_xyn,您需要使用 .* 运算符:(n.*pf)(10, 20);。这相当于n.set_xy(10, 20);

  • 由于opM* 类型(指向M 对象的指针),您需要使用-&gt;* 运算符并调用pf 指向的函数: (op-&gt;*pf)(30, 40);,相当于op-&gt;set_xy(30, 40);

内部sum

  • 这些示例只是指向成员/实例变量的指针,而不是成员函数。它只是演示了如何使用这些类型的指针将 m.xm.y 相加。

【讨论】:

    【解决方案2】:

    看看Pointer to class data。而对于错误,->* 是一个运算符,你不能在它们之间放置一个空格。

    【讨论】:

      【解决方案3】:

      问题是由于op-&gt; *pf 处的额外空格

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

      我认为@fefe 可能已经在评论中说明了原因。 -&gt;* 是单个运算符,类似于 .*。因此,如果将这两个分开,则会导致语法不同,从而导致编译器错误。

      【讨论】:

      • 我在某处读到 c++ 不关心空格。让我们试试它是否有效。
      • @jeet.mg:运营商是-&gt;*。你不能在任何你喜欢的地方放空格(比如dele tedelete不一样)
      • 这个问题解决了。有人可以解释一下它的工作原理吗?
      • @jeet.mg,这是一个不同的问题。您可能必须首先查看您的代码,如果无法理解,您可以发布另一个问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-24
      • 1970-01-01
      • 2013-07-15
      • 2014-05-18
      • 1970-01-01
      • 2011-05-14
      • 2013-07-19
      相关资源
      最近更新 更多