指向成员变量的多态指针
我正在尝试以多态方式使用指向成员变量的指针。
这有效:
struct Foo
{
int member0;
int member1;
int* getMember( int i )
{
static int Foo::* table[2] = { &Foo::member0, &Foo::member1 };
return &( this->*table[i] );
}
};
这不起作用,因为成员不是同一类型(BaseClass):
struct Foo
{
SubClassA member0;
SubClassB member1;
BaseClass* getMember( int i )
{
static BaseClass Foo::* table[2] = { &Foo::member0, &Foo::member1 };
return &( this->*table[i] );
}
};
g++ 报告的错误是:
[...] invalid conversion from 'SubClassA Foo::*' to 'BaseClass Foo::*'
[...] invalid conversion from 'SubClassB Foo::*' to 'BaseClass Foo::*'
有没有办法使这项工作有效,即将成员指针“向上转换”到其基类?
I'm trying to use pointers to member variables in a polymorphic fashion.
This works:
struct Foo
{
int member0;
int member1;
int* getMember( int i )
{
static int Foo::* table[2] = { &Foo::member0, &Foo::member1 };
return &( this->*table[i] );
}
};
This does not, since the members are not of the same type (BaseClass):
struct Foo
{
SubClassA member0;
SubClassB member1;
BaseClass* getMember( int i )
{
static BaseClass Foo::* table[2] = { &Foo::member0, &Foo::member1 };
return &( this->*table[i] );
}
};
The error reported by g++ is:
[...] invalid conversion from 'SubClassA Foo::*' to 'BaseClass Foo::*'
[...] invalid conversion from 'SubClassB Foo::*' to 'BaseClass Foo::*'
Is there a way to make this work, ie to "upcast" the member pointer to its base class?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这是不可能的。由于多重继承,基地址并不总是与派生地址相同。您需要一些隐藏的地址调整魔法来将一个地址转换为另一个地址,而指向成员的指针作为一个非常简单的对象(基本上是整数偏移量)无法容纳这种魔法。
确实,地址调整只是有时需要,而当不需要时,原则上可以允许指向成员的多态指针。但为了简单性和一致性,我们并没有这么做。
您可以使用指向接受 Foo* 并返回 BaseClass* 的函数(或类函数对象)的指针,而不是指向成员的指针。不过,您必须为每个成员创建一个单独的函数。
This is not possible. Because of multiple inheritance, address-of-base is not always the same as address-of-derived. You need some hidden address adjustment magic to convert one to the other, and a pointer-to-member, being a very simple object (basically an integer offset) cannot accomodate this magic.
It is true that address adjustment only needed sometimes, and when it is not needed, polymorphic pointers-to-members could in principle be allowed. But this is not done, for simplicity and consistency.
Instead of pointers-to-members, you can use pointers to functions (or function-like objects) that accept a Foo* and return a BaseClass*. You will have to make a separate function for each member though.
为了鲁棒性,你必须检查
i
是否在 0 和 1 的范围内;所以你可以考虑这种简化的方法。For robustness you have to anyway check if the
i
is within the range or 0 and 1; so you can think for this simplified approach.更简单的方法是完全跳过成员数据指针。
The easier way to do it would be to skip the member data pointers altogether.