7

我想编写成员指针。基本上我有一个不同成员的主类。如何为指向该类成员的成员的主类创建成员指针。我希望下面的代码解释了我正在尝试做的事情:

  struct SubUnit
  {
    int   value;
  };
  struct Unit
  {
    SubUnit sub_unit;
  };

  void Test()
  {
    SubUnit Unit::* ptr1 = &Unit::sub_unit; // WORKING
    int Unit::* ptr2 = &Unit::sub_unit::value; // NOT WORKING !
  }
4

4 回答 4

5

看来您必须分两个阶段进行:

SubUnit Unit::*pSub = &Unit::sub_unit;
int SubUnit::*pValue = &SubUnit::value;

Unit u;
int theVal = (u.*pSub).*pValue;
于 2014-01-28T15:37:31.750 回答
3

这里子类的使用比较混乱,因为一般子类是用来继承的,所以我们来说说一个数据成员sub_unit是一个数据成员Unit

你所要求的是不可能的,Unit::*只能表示其Unit本身或其基类之一的偏移量:

struct SubUnit { int value; };

struct Unit: SubUnit {};

int main() { int Unit::* p = &Unit::value; }
于 2014-01-28T15:23:46.590 回答
2

这似乎是这个问题的重复:
嵌套数据成员指针 - 不可能?

接受答案的症结在于:

指向成员的指针只能由 &qualified_id 类型的表达式形成,这不是你的情况

C++ 标准在第 8.3.3 段中说:
指向成员的指针:

在声明 TD 中,其中 D 具有以下形式

  nested-name-specifier * attribute-specifier-seqopt cv-qualifier-seqopt D1

而nested-name-specifier表示一个类,声明T D1中标识符的类型为“derived-declarator-type-list T”,则D的标识符类型为“derived-declarator-type-列出 cv qualifier-seq 指向类型 T 的类嵌套名称说明符成员的指针”。可选的属性说明符序列(7.6.1)属于指向成员的指针。

事实证明,有一种方法可以做你想做的事,这似乎适用于我当前的编译器(apple llvm 5.0)。但是,它非常依赖于实现,我绝对建议不要在任何类型的生产代码中使用此解决方案

//added a few data members to make it non-trivial
struct SubUnit {
    double d;
    int   value;
};
struct Unit {
    bool b;
    char c;
    SubUnit sub_unit;
};

intptr_t suOffset = offsetof(Unit, sub_unit);
intptr_t intOffset = offsetof(SubUnit, value);
intptr_t totalOffset = suOffset + intOffset;

// there is no way to convert this offset directly in a
// pointer-to-member AFAIK, so we have to trick a bit
int Unit::* pui = nullptr;
auto puiAddr = &pui;
intptr_t* puiAddrAsIntPtrPtr = reinterpret_cast<intptr_t*>(puiAddr);
*puiAddrAsIntPtrPtr = totalOffset;

//pui should now "point to the right offset"
//let's test it
Unit u;
u.sub_unit.value = 123456;

int val = u .* pui;
std::cout << "val: " << val << std::endl;
于 2014-01-28T15:32:31.930 回答
0

可以使用 lambda 构建解决方法:

    struct SubUnit
    {
        int   value;
    };
    struct Unit
    {
        SubUnit sub_unit;
    };

    void Test()
    {
        auto  composed_mem_ptr = [](Unit & unit) -> int&{ return  unit.sub_unit.value; };
        Unit  unit0{};
        composed_mem_ptr(unit0) = 7;
    }
于 2014-01-28T19:04:31.590 回答