【问题标题】:How Does Getting the Address of a Class Member Through a Scope Resolution Operator Work When Using a Pointer-to-Member?使用指针成员时如何通过范围解析运算符获取类成员的地址?
【发布时间】:2013-07-19 07:48:55
【问题描述】:

当使用指向成员的指针(也称为点星或箭头星)来访问类成员时,我们可以使用以下语法:

A * pa;
int A::*ptm2 = &A::n;
std::cout << "pa->*ptm: " << pa->*ptm << '\n';

我的问题是&amp;A::n 语句是如何工作的?

在上面的例子中,n 是一个变量。如果n 不是一个成员变量,而是一个函数(并且我们定义了一个指向成员函数的指针而不是指向成员的指针),我可能会认为因为类的函数可以有效静态(参见 Nemo 的评论),我们可以通过&amp;A::some_function 找到一个类的函数地址。但是我们如何通过类作用域解析来获取非静态类成员的地址呢?当我打印&amp;A::n 的值时,这更加令人困惑,因为输出仅仅是1

【问题讨论】:

  • 对于成员变量,它是从对象实例开始的偏移量。 -&gt;* 大致相当于仅将其 LHS(实例)和 RHS(偏移)部分相加。
  • @syam 这就是我的想法。但是,如果我为多个成员变量打印&amp;A::member_variable,我会为所有这些变量得到1
  • 一个类的函数不一定是“有效静态的”;考虑虚函数、多重继承等......“指向成员的指针”的内部表示可能会变得非常复杂。一些实现最多使用 16 个字节(参见,例如,lazarenko.me/2013/04/28/cc-pointers-to-member-functions
  • @user2141130 那是因为当您尝试打印它时,它不会打印偏移量本身,而是转换为其他东西(我认为是布尔值,但我无法检查是否正确现在——无论如何你明白了,你不是在打印你的想法)。
  • @Nemo 好点,谢谢。我做了一个小修改,以避免给别人我的坏主意!

标签: c++ class pointers scope pointer-to-member


【解决方案1】:

当您声明指向成员数据的指针时,它不受任何特定实例的限制。如果您想知道给定实例的数据成员的地址,您需要在执行.*-&gt;* 之后获取结果的地址。例如:

#include <stdio.h>

struct A
{
  int n;
};

int main()
{
  A a  = {42};
  A aa = {55};
  int A::*ptm = &A::n;
  printf("a.*ptm: %p\n", (void *)&(a.*ptm));
  printf("aa.*ptm: %p\n", (void *)&(aa.*ptm));
}

打印为一种可能的输出:

a.*ptm: 0xbfbe268c
aa.*ptm: 0xbfbe2688

【讨论】:

    猜你喜欢
    • 2012-01-23
    • 2021-12-22
    • 1970-01-01
    • 2011-06-11
    • 1970-01-01
    • 2017-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多