【问题标题】:Pointer to a member function指向成员函数的指针
【发布时间】:2016-11-07 22:30:27
【问题描述】:

有结构

struct Person{
    Person( int i , int g):id(i),age(g){};
    int id;
    int age;
};

我可以通过将指向成员数据的指针作为参数传递给函数来动态返回成员数据。例如

int extract( Person * p , int Person::* param)
{   
    return p ->*param;
}

并使用

调用
Person *p = new Person (10 , 20 );
cout << extract(p , &Person::id )<< endl;

但我的问题是,为什么这行得通?我们传递 &amp;Person::id 基本上是 memory ,但 Person 是一个违反定义的 r 值。

感谢所有对我可能对主题的误解的解释/澄清。 谢谢。

【问题讨论】:

  • Person 是类型名称,而不是右值
  • &amp;Person::id 在内部表示为任何Person 对象的偏移量。
  • “我们正在传递 &amp;Person::id 基本上是内存” - 你到底是什么意思?什么是“基本记忆”?
  • 代码中的任何地方都没有 Person 类型的右值。也没有指向成员函数的指针,所以请更改误导性标题。

标签: c++ c++11 rvalue pointer-to-member


【解决方案1】:

C++ 中指向成员的指针可以理解为“偏移”定义。虽然当你有虚函数等时会有一些复杂性,但在你的情况下这已经足够了。

所以,基本上你的代码就像(如果我们将数据类型转换为“原始”数据)

int extract(void *p, int offset)
{
    return *((int*)(p+offset));
}

(从技术上讲,上面的代码是不能编译的,因为void *指针不能用于加法表达式,因为编译器不知道指针的大小,但我们暂时忽略它。)

当你调用它时,代码看起来像

extract(p, __offsetof(Person, id));

其中__offsetof 是一个伪运算符,编译器将在编译时计算它。

你可以看到这里没有魔法。 C++ 帮助您的是偏移量在一种特殊的数据类型中受到保护,因此您不能更改其内部,从而避免破坏。

有关 C/C++ 指针转换和算术的其他信息

上面的代码对于 C/C++ 用户来说是非常基础的,虽然它不是 C++ 专业人士希望看到的形式(应该使用 static_castreinterpret_cast 而不是 C stype 转换)。

我看到提问者询问有关 C/C++ 指针算法的进一步解释,这有点离题,因为它与此处提出的问题无关,因此我提供了有关此主题的进一步参考。

Pointer Arithmetic

http://www.technoplaza.net/programming/lesson9p2.php

http://www.informit.com/articles/article.aspx?p=686170&seqNum=8

【讨论】:

  • 感谢您的回答,您介意解释一下 return ((int)(p+offset));这是我第一次遇到这样的事情。我认为它是指向函数的指针,但函数的返回类型表明它应该是对将指针返回到 int 的函数的一些取消引用。谢谢!
  • @trolkura:它是*reinterpret_cast&lt;int*&gt;(p+offset) 的简写。此外,它在这里用于建议可能的实现。实际编译器的工作方式可能不同,尤其是在优化之后。
  • @trolkura 另外,您需要知道intint* 非常不同。前者是123之类的整数类型,后者是指向int的指针类型。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多