简体   繁体   English

C ++:指向复合类数据成员的指针

[英]C++: Pointer to composite class data member

Is it possible to access a composite class data member with pointers to members ? 是否可以使用指向成员的指针访问复合类数据成员? The following code is not valid but demonstrate the need. 以下代码无效,但可以证明需要。

For example: 例如:

class A
{
public:
    float fA;
};

class B
{
public:
    float fB;
    A a;
};

void test()
{
    // Use of member pointer to access B::fB member
    float B::*ptr = &B::fB; // -> OK
    B myB;
    myB.*ptr = 25.;

    // Use of member pointer to access B::a.fA member ???
    float B::*ptr2 = &B::a.fA; // -> ERROR
    B myB.*ptr2 = 25.;
}

I've complete my question here : Pointer to composite class data member - Part 2 我在这里完成了我的问题: 指向复合类数据成员的指针-第2部分

The obvious "reason" here is because fA is not a member of B . 这里明显的“原因”是因为fA不是B的成员。 In this particular case, implementing it would probably not cause any particular problems, both orthogonality rules, and for member functions, I don't think it could be implemented. 在这种特殊情况下,实现它可能不会引起任何特殊问题,无论是正交性规则,还是对于成员函数而言,我都不认为它可以实现。

What you can do, of course, is take the address of the A member of B , then get to fA through it: 当然,您可以做的是获取BA成员的地址,然后通过它到达fA

A B::*ptr = &B::a;
(myB.*ptr).fa = 25.;

, for example. , 例如。 (I'm not sure that the parentheses are needed. It's not a constrution that I use often enough to have the precedences in my head.) (我不确定是否需要使用括号。这并不是我经常使用以使优先次序浮于水面的解释。)

I agree with commenters, that probably you should ask how to do what you want , not how to do what you think will do what you want :) 我同意评论者的意见,也许您应该问如何做自己想做的事情 ,而不是问如何做自己认为会做的事情 :)

As for the question: no, you cannot access B::a.fA in this way. 至于问题:不,您不能以这种方式访问B::a.fA However, you can do the following: 但是,您可以执行以下操作:

A myA;
float A::*ptr2 = &A::fA; // -> OK now
myB.a.*ptr2 = 25.;

Or the following: 或以下内容:

A B::*ptr3 = &B::a; 
(myB.*ptr3).fA = 1.0f;  // -> OK too

That is some weird looking syntax but if I understand you correctly, you are trying to access fA through class B. If that is the case, then you will need to create an instance of class B before class A is available to be accessed. 那是一些看起来很奇怪的语法,但是如果我对您的理解是正确的,那么您正在尝试通过类B访问fA。如果是这种情况,那么您将需要在可以访问类A之前创建类B的实例。 Basically, if B doesn't exist, you can't access what is inside of it. 基本上,如果B不存在,则无法访问其中的内容。 The error is just what it sounds like, "left of .fA must have a class/struct/union" meaning your compiler can't figure out what is to the left of fA so the "a" is undefined or doesn't exist. 该错误听起来像是,“。fA的左边必须有一个类/结构/联合”,这意味着您的编译器无法弄清楚fA的左边是什么,因此“ a”未定义或不存在。 Also, you have a redefinition error in there with B myB :) 另外,您在其中使用B myB存在重新定义错误:)

No you cannot because the C++ syntax does not allow it. 不,您不能因为C ++语法不允许它。 I don't see anything really special about what you're trying to do, but it's simply not considered in the language. 对于您要执行的操作,我看不出有什么特别的地方,但是在语言中根本没有考虑到它。

Note however that a pointer to data member is an object that given an instance will return a reference to a specific data member. 但是请注意,指向数据成员的指针是给定实例的对象将返回对特定数据成员的引用。 You can implement this functionality manually relaxing the limitations: 您可以手动实现此功能,以放松限制:

struct A
{
    double x;
    double y;
    static double& x_of(void *p) { return ((A *)p)->x; }
    static double& y_of(void *p) { return ((A *)p)->y; }
};

struct B
{
    double z;
    A a;
    static double& x_of(void *p) { return ((B *)p)->a.x; }
    static double& y_of(void *p) { return ((B *)p)->a.y; }
    static double& z_of(void *p) { return ((B *)p)->z; }
};

The type of the pointer is just double& (*)(void *) and you can use this kind of trick even for example to return as member an element of an array. 指针的类型只是double& (*)(void *) ,您甚至可以使用这种技巧来返回数组元素作为成员。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM