C++ 指向成员变量的多态指针

C++ 指向成员变量的多态指针,c++,polymorphism,pointer-to-member,C++,Polymorphism,Pointer To Member,我试图以多态方式使用指向成员变量的指针 这项工作: struct Foo { int member0; int member1; int* getMember( int i ) { static int Foo::* table[2] = { &Foo::member0, &Foo::member1 }; return &( this->*table[i] ); } }; 由于成员不属于同一类型(基类),因此不会

我试图以多态方式使用指向成员变量的指针

这项工作:

struct Foo
{
   int member0;
   int member1;

   int* getMember( int i )
   {
     static int 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::*'

有没有一种方法可以做到这一点,即将成员指针“向上投射”到其基类?

更简单的方法是完全跳过成员数据指针

getMember(int i) {
    BaseClass* ptr[2] = { &member0, &member1 };
    return ptr[i];
}
BaseClass*getMember(const int i)
{
开关(一)
{
案例0:返回&成员0;
案例1:退货和会员1;
默认值:抛出;
}
}

对于健壮性,您必须检查
i
是否在范围内或0和1之间;因此,您可以考虑这种简化方法。

这是不可能的。由于多重继承,基的地址并不总是与派生的地址相同。您需要一些隐藏的地址调整魔术来将一个转换为另一个,而一个指向成员的指针,作为一个非常简单的对象(基本上是一个整数偏移量),无法适应这种魔术

诚然,地址调整只在某些时候需要,而在不需要的时候,原则上可以允许使用指向成员的多态指针。但为了简单性和一致性,这并没有做到


您可以使用指向接受Foo*并返回基类*的函数(或类似函数的对象)的指针,而不是指向成员的指针。不过,您必须为每个成员单独设置一个函数。

问题的形式非常糟糕。你的代码现在有什么问题?有错误吗?发布更多信息你想做什么,你面临什么问题。@Nawaz是的,我几乎试图回答这个问题,但无法说出他想做什么或出了什么问题。我添加了错误消息和一些说明。这会更容易,但也会更慢?我使用静态指针的原因是为了最小化查找时间…@hmn:我很想看到这个小函数的程序集,你可能会对编译器生成的内容感到惊讶…只有当成员数很小时,这个函数才很小;-)@hmn:编译器很可能会将其优化为一个跳转表,然后计算适当的值——就像它一样,延迟初始化。即使没有,本地内存中的100个周期也不是一个很大的成本。你应该描述并证明这是一个问题。还有-一百名成员?真正地这只是…如果编译器不需要每次通过函数初始化指针数组,那么这只是O(1)。似乎我可以通过使用C cast
(基类Foo::*)&Foo::member0
来解决这个问题。我可以断言,在这些成员类型中没有使用多重继承。。。但我可能会转而使用基类指针数组。@hmn那又怎样?通过使用C类型转换来做一些事情完全证明不了什么,因为如果找不到有用的、已定义的类型转换,它将退化为一个
重新解释\u类型转换
,其中除少数情况外,取消引用在所有情况下都是未定义的行为(如果在取消引用之前将其重新转换,则其余情况都是“有用的”)。。。这是不允许的例子。事实上,你的编译器只是做了它能做的最不令人惊讶的事情,而这一次恰好可以工作,这并不是一个好主意;不是。
getMember(int i) {
    BaseClass* ptr[2] = { &member0, &member1 };
    return ptr[i];
}
BaseClass* getMember(const int i)
{
  switch(i)
  {
  case 0: return &member0;
  case 1: return &member1;
  default: throw <exception>;
  }
}