你能有一个指向子对象类的数据成员的指针吗?

问题描述 投票:0回答:3

我对一件事感兴趣 - 在 C++ 中,我们有指向数据成员的指针,例如:

struct A
{
  int a_1 = 1;
};

A a;
int A::* p_a = &A::a_1;
    
a.*p_a = 10;

但是如果我有这样的东西:

struct B
{
  int b_1 = 11;
};

struct A
{
  int a_1 = 1;
  
  B b;
};

...其中

B
类型的对象存储在
A
类型的对象中 - 有没有办法拥有指向子对象类的数据成员的指针,即像这样:

A a;
/*???*/ p_b = &A::B::b_1;

a.*p_b = 10; // after that - a.b.b_1 is equals to 10

希望我说清楚了:)

c++ pointers pointer-to-member
3个回答
4
投票

指向成员的组合指针只是指向各个结构成员的两个单独的独立指针(有点像二维数组索引只是一对常规的一维数组索引)。

auto [pa,pb] = std::tuple(&A::b, &B::b_1);
a.*pa.*pb = 42;

如果您更喜欢像

a->*pab
这样的单一运算符语法,则需要将两个指向成员的指针打包到单个对象中,并为其重载
operator->*
。这是一个相当简单的练习。


2
投票

它仍然是指向B类成员的指针,因为b是B的成员:

struct B
{
  int b_1 = 11;
};

struct A
{
  int a_1 = 1;
  
  B b;
};

int main()
{
    A a;
    int B::* p_b = &B::b_1;
    a.b.*p_b = 42;
    std::cout << a.b.b_1 << std::endl; 
}

你实际上甚至可以写

auto B::* p_b
。指向成员的指针是相对于封闭类的,并且您的代码中不存在名为
A::B
的类。它可以是命名空间中的类、嵌套类或 A 的基类(如果 A 派生自 B)。

请注意,指向基类成员的指针与指向派生类成员的指针兼容:

struct A : public B
{
  int a_1 = 1;
  
  B b;
};

int main()
{
    A a;
    int B::* p_b = &A::B::b_1;  // this is explicitly a B::*
    int A::* p_ab = &B::b_1;    // this is compatible
    a.*p_ab = 42;
    std::cout << a.*p_b << std::endl;
}

0
投票

编辑:

我写下我的答案时不明白OP正在寻找一个指向成员的指针,而不仅仅是一个标准指针。我将保留它,以防它以某种方式帮助将来的任何人解决他们的问题,但这不是原始问题的正确答案。

原答案:

可以,你只需要声明你的B变量,然后你就可以引用你嵌套的A变量。例如,我们可以将指针保存在它自己的变量中,然后使用该指针引用 A:

#include <iostream>
using namespace std;

struct A {
    int val = 1;
};

struct B {
    A aWithinB;
};

int main(){
    B myB;

    //pointer to the A held by B
    A *a_ptr = &myB.aWithinB;

    //print val from the nested A using the pointer
    cout << "Val = " << a_ptr->val << endl;
}

输出:

Val = 1
© www.soinside.com 2019 - 2024. All rights reserved.