指向成员的成员的指针

use*_*676 1 c++ pointer-to-member c++11

C++ 允许定义指向类成员的指针,例如:

struct A
{
  int i;
};

void a()
{
  int A::*p = &A::i;
}
Run Code Online (Sandbox Code Playgroud)

但是如果我想要一个指向像这样更深“级别”的成员的指针怎么办?

struct A
{
  int i;
  struct B{int j;};
  B b;
};

void a()
{
  int A::*p = &A::b::j;
}
Run Code Online (Sandbox Code Playgroud)

从理论上讲,如果指向成员的指针从对象的开头编译为偏移,这可能很容易被语言支持,尽管像虚拟/钻石继承这样的事情可能会使这变得太复杂

在没有性能损失或未定义行为的情况下实现这一目标的最简单方法是什么?

我的第一个想法是只使用偏移量并使用对象上的原始指针,但这似乎不是定义的行为,并且也会使编译器无法检测我是否指向具有正确类型的实际字段

dfr*_*fri 5

您只能为给定类的实际数据成员定义指向数据成员的指针。

您声明了一个嵌套的类类型在这里并不是特例:您可以提取一个数据成员A::B的指针并将指向数据成员的指针应用到对象的b成员(类型A::B)上A

#include <iostream>

struct A {
  int i;
  struct B{ int j; };
  B b;
};

int main() {
    A a{1, {42}};  // a.b.j is 42
    
    // Declare a pointer-to-data-member of B (which
    // is a nested class in A).
    int A::B::*p = &A::B::j;
    
    // Apply to an actual 'B' object to retrieve
    // the data member value pointed to.
    std::cout << a.b.*p;  // 42
}
Run Code Online (Sandbox Code Playgroud)

但是,如果您想在A对象上应用指向数据成员的指针,那么您可以获得的最好的方法是指向数据成员的指针b

对于嵌套类对象,您始终可以使用指向数据成员指针的嵌套指针:

int main() {
    A a{1, {42}};  // a.b.j is 42
    
    A::B A::*pb = &A::b;
    int A::B::*pj = &A::B::j;
    std::cout << (a.*pb).*pj;  // 42
}
Run Code Online (Sandbox Code Playgroud)