指向数据成员的数据成员的指针

Pointer-to-data-member-of-data-member

本文关键字:数据成员 指针      更新时间:2023-10-16

我有以下代码(针对这个问题进行了简化):

struct StyleInfo
{
    int width;
    int height;
};
typedef int (StyleInfo::*StyleInfoMember);
void AddStyleInfoMembers(std::vector<StyleInfoMember>& members)
{
    members.push_back(&StyleInfo::width);
    members.push_back(&StyleInfo::height);
}

现在,我们不得不对此进行一些重组,我们做了这样的事情:

struct Rectangle
{
    int width;
    int height;
};
struct StyleInfo
{
    Rectangle size;
};
typedef int (StyleInfo::*StyleInfoMember);
void AddStyleInfoMembers(std::vector<StyleInfoMember>& members)
{
    members.push_back(&StyleInfo::size::width);
    members.push_back(&StyleInfo::size::height);
}

如果这一切看起来像是一件愚蠢的事情,或者如果你觉得出于某种原因有一个很好的机会在这里应用BOOST,我必须警告你,我真的把它简化为手头的问题:

错误C3083:"size":"::"左侧的符号必须是类型

我想说的是,我不知道在这里使用什么是正确的语法。"StyleInfo"可能不是从一开始就获取地址的正确类型,但在我的项目中,我可以解决这类问题(那里有一个完整的框架)。我只是不知道该如何指向这个成员中的一个。

记住,指向成员的指针就像使用成员一样。

 Obj x;
 int  y = (x.*)ptrMem;

但是像普通成员一样,您不能使用成员访问机制访问子类的成员。因此,您需要像访问对象的成员一样访问它(在您的情况下,通过size成员)。

#include <vector>
#include <iostream>

struct Rectangle
{
    int width;
    int height;
};
struct StyleInfo
{
    Rectangle size;
};
typedef Rectangle   (StyleInfo::*StyleInfoMember);
typedef int         (Rectangle::*RectangleMember);
typedef std::pair<StyleInfoMember,RectangleMember>  Access;
void AddStyleInfoMembers(std::vector<Access>& members)
{
    members.push_back(std::make_pair(&StyleInfo::size,&Rectangle::width));
    members.push_back(std::make_pair(&StyleInfo::size,&Rectangle::height));
}

int main()
{
    std::vector<Access>     data;
    AddStyleInfoMembers(data);
    StyleInfo       obj;
    obj.size.width  = 10;
    std::cout << obj.*(data[0].first).*(data[0].second) << std::endl;
}

这不是我建议做的事情

另一种选择(我建议更少)是找到从类开头开始的字节偏移量,然后将其添加到对象地址中。显然,这将涉及到大量的前后投法,所以这看起来比上面的更糟。

这肯定有可能吗?老实说,我不知道,从来没有打过多少指针对成员。

假设您使用的是非POD类型(我知道您不是,但语法必须支持它)。然后,指向成员的指针可能需要封装的不仅仅是基指针的偏移量。根据多重继承的实现方式,也可能存在间接继承。对于多个级别的成员间接寻址,这可能会变得任意复杂,对于必须具有固定大小的类型来说,这是一个很大的要求。

也许你需要一个成对的向量,其类型由以下定义:

typedef Rectangle (StyleInfo::*StyleInfoMember);
typedef int (Rectangle::*RectangleMember);

依次应用每个以到达您想要的位置。当然,这仍然不允许您构建从StyleInfo到StyleInfo成员的任意成员的映射向量,因为它们不会全部通过Rectangle。为此,你可能需要打开一罐函子。。。

size(如&StyleInfo::size::width)不是类型的名称。

请尝试size->width或size.width,具体取决于"AddStyleInfoMembers"对大小的了解程度。